转自 http://blog.csdn.net/acm_yuuji/article/details/27642221
http://blog.csdn.net/coslay/article/details/50382252
过程:
一些网站的数据库管理着用户的ID及口令,口令以MD5等加密后的形式存在,但是有些时候可能数据库泄露,HASH值被攻击者获取,如果此HASH值对应的口令是弱口令(被很多用户采用),则黑客可以通过此HASH暴力破解获取其他用户的ID及口令,破坏数据的机密性。
通过加入盐值(salt)即盐化可以很好的防治这种攻击手段。盐值是一组随机的字符串,通过插入在口令后进行HASH算法,这样即使是相同的口令,插入不同的盐值后生成的HASH值也是不相同的,由于MD5的不可逆性,想要逆向破解MD5也是非常耗时间的。
具体的流程是:
用户注册时:
1、用户在网站注册时提供ID与口令
2、系统为用户分配盐值
3、盐值插入口令后进行HASH
4、将ID,HASH值与盐值存入数据库
身份验证时: 1、用户提供ID与口令
2、系统在数据库中通过用户提供的ID查找HASH值与盐值
3、将盐值插入用户提供的口令后进行HASH
4、将HASH值与数据库中的HASH值比较,相等则验证成功,反之验证失败
iOS 实现:
CCHmac
转自http://stackoverflow.com/questions/14516191/xcode-ios-hmac-sha-256-hashing
NSString * parameters = @"string to hash";
NSString *salt = @"saltStringHere";
NSData *saltData = [salt dataUsingEncoding:NSUTF8StringEncoding];
NSData *paramData = [parameters dataUsingEncoding:NSUTF8StringEncoding];
NSMutableData* hash = [NSMutableData dataWithLength:CC_SHA256_DIGEST_LENGTH ];
CCHmac(kCCHmacAlgSHA256, saltData.bytes, saltData.length, paramData.bytes, paramData.length, hash.mutableBytes);
NSString *base64Hash = [hash base64EncodedStringWithOptions:0];
SHA1/MD5+Base64
Objective-c实现MD5和SHA1算法相对还是比较简单的,可以直接调用系统的C/C++共享库来实现调用
MD5即Message Digest Algorithm 5(信息-摘要算法 5),用于确保信息传输完整一致。是计算机广泛使用的杂凑算法之一
SHA即Secure Hash Algorithm(安全散列算法) 是美国国家安全局 (NSA) 设计,美国国家标准与技术研究院 (NIST) 发布的一系列密码散列函数。
使用方式如下:
MD5加密方式
SString *) md5
{
const char *cStr = [self UTF8String];
unsigned char digest[CC_MD5_DIGEST_LENGTH];
CC_MD5( cStr, strlen(cStr), digest );
NSMutableString *output = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
for(int i = 0; i < CC_MD5_DIGEST_LENGTH; i++)
[output appendFormat:@"%02x", digest[i]];
return output;
}
SHA1加密方式
- (NSString*) sha1
{
const char *cstr = [self cStringUsingEncoding:NSUTF8StringEncoding];
NSData *data = [NSData dataWithBytes:cstr length:self.length];
uint8_t digest[CC_SHA1_DIGEST_LENGTH];
CC_SHA1(data.bytes, data.length, digest);
NSMutableString* output = [NSMutableString stringWithCapacity:CC_SHA1_DIGEST_LENGTH * 2];
for(int i = 0; i < CC_SHA1_DIGEST_LENGTH; i++)
[output appendFormat:@"%02x", digest[i]];
return output;
}
当然也可以结合BASE64来使用,这里的BASE64编码使用 GTMBase64实现,需要导入
- (NSString *) sha1_base64
{
const char *cstr = [self cStringUsingEncoding:NSUTF8StringEncoding];
NSData *data = [NSData dataWithBytes:cstr length:self.length];
uint8_t digest[CC_SHA1_DIGEST_LENGTH];
CC_SHA1(data.bytes, data.length, digest);
NSData * base64 = [[NSData alloc]initWithBytes:digest length:CC_SHA1_DIGEST_LENGTH];
base64 = [GTMBase64 encodeData:base64];
NSString * output = [[NSString alloc] initWithData:base64 encoding:NSUTF8StringEncoding];
return output;
}
- (NSString *) md5_base64
{
const char *cStr = [self UTF8String];
unsigned char digest[CC_MD5_DIGEST_LENGTH];
CC_MD5( cStr, strlen(cStr), digest );
NSData * base64 = [[NSData alloc]initWithBytes:digest length:CC_MD5_DIGEST_LENGTH];
base64 = [GTMBase64 encodeData:base64];
NSString * output = [[NSString alloc] initWithData:base64 encoding:NSUTF8StringEncoding];
return output;
}
通过拓展NSString,实现完整功能,全部代码
@interface NSString (encrypto)
- (NSString *) md5;
- (NSString *) sha1;
- (NSString *) sha1_base64;
- (NSString *) md5_base64;
- (NSString *) base64;
@end
@implementation NSString (encrypto)
- (NSString*) sha1
{
const char *cstr = [self cStringUsingEncoding:NSUTF8StringEncoding];
NSData *data = [NSData dataWithBytes:cstr length:self.length];
uint8_t digest[CC_SHA1_DIGEST_LENGTH];
CC_SHA1(data.bytes, data.length, digest);
NSMutableString* output = [NSMutableString stringWithCapacity:CC_SHA1_DIGEST_LENGTH * 2];
for(int i = 0; i < CC_SHA1_DIGEST_LENGTH; i++)
[output appendFormat:@"%02x", digest[i]];
return output;
}
-(NSString *) md5
{
const char *cStr = [self UTF8String];
unsigned char digest[CC_MD5_DIGEST_LENGTH];
CC_MD5( cStr, strlen(cStr), digest );
NSMutableString *output = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
for(int i = 0; i < CC_MD5_DIGEST_LENGTH; i++)
[output appendFormat:@"%02x", digest[i]];
return output;
}
- (NSString *) sha1_base64
{
const char *cstr = [self cStringUsingEncoding:NSUTF8StringEncoding];
NSData *data = [NSData dataWithBytes:cstr length:self.length];
uint8_t digest[CC_SHA1_DIGEST_LENGTH];
CC_SHA1(data.bytes, data.length, digest);
NSData * base64 = [[NSData alloc]initWithBytes:digest length:CC_SHA1_DIGEST_LENGTH];
base64 = [GTMBase64 encodeData:base64];
NSString * output = [[NSString alloc] initWithData:base64 encoding:NSUTF8StringEncoding];
return output;
}
- (NSString *) md5_base64
{
const char *cStr = [self UTF8String];
unsigned char digest[CC_MD5_DIGEST_LENGTH];
CC_MD5( cStr, strlen(cStr), digest );
NSData * base64 = [[NSData alloc]initWithBytes:digest length:CC_MD5_DIGEST_LENGTH];
base64 = [GTMBase64 encodeData:base64];
NSString * output = [[NSString alloc] initWithData:base64 encoding:NSUTF8StringEncoding];
return output;
}
- (NSString *) base64
{
NSData * data = [self dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
data = [GTMBase64 encodeData:data];
NSString * output = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
return output;
}
@end
实现时候不要忘记导入CC相关的库的头文件
CommonCrypto/CommonDigest.h
另一种实现:
//
//NSString+SHA.h
//
#import <Foundation/Foundation.h>
#import <CommonCrypto/CommonDigest.h>
#import <CommonCrypto/CommonCryptor.h>
@interface NSString(SHA)
-(NSString *) sha1;
-(NSString *) sha224;
-(NSString *) sha256;
-(NSString *) sha384;
-(NSString *) sha512;
@end
//
//NSString+SHA.m
//
#import "NSString+SHA.h"
@implementation NSString(SHA)
- (NSString*) sha1
{
const char *cstr = [self cStringUsingEncoding:NSUTF8StringEncoding];
NSData *data = [NSData dataWithBytes:cstr length:self.length];
uint8_t digest[CC_SHA1_DIGEST_LENGTH];
CC_SHA1(data.bytes, data.length, digest);
NSMutableString* output = [NSMutableString stringWithCapacity:CC_SHA1_DIGEST_LENGTH * 2];
for(int i = 0; i < CC_SHA1_DIGEST_LENGTH; i++)
[output appendFormat:@"%02x", digest[i]];
return output;
}
- (NSString*) sha224
{
const char *cstr = [self cStringUsingEncoding:NSUTF8StringEncoding];
NSData *data = [NSData dataWithBytes:cstr length:self.length];
uint8_t digest[CC_SHA224_DIGEST_LENGTH];
CC_SHA224(data.bytes, data.length, digest);
NSMutableString* output = [NSMutableString stringWithCapacity:CC_SHA224_DIGEST_LENGTH * 2];
for(int i = 0; i < CC_SHA224_DIGEST_LENGTH; i++)
[output appendFormat:@"%02x", digest[i]];
return output;
}
- (NSString*) sha256
{
const char *cstr = [self cStringUsingEncoding:NSUTF8StringEncoding];
NSData *data = [NSData dataWithBytes:cstr length:self.length];
uint8_t digest[CC_SHA256_DIGEST_LENGTH];
CC_SHA256(data.bytes, data.length, digest);
NSMutableString* output = [NSMutableString stringWithCapacity:CC_SHA256_DIGEST_LENGTH * 2];
for(int i = 0; i < CC_SHA256_DIGEST_LENGTH; i++)
[output appendFormat:@"%02x", digest[i]];
return output;
}
- (NSString*) sha384
{
const char *cstr = [self cStringUsingEncoding:NSUTF8StringEncoding];
NSData *data = [NSData dataWithBytes:cstr length:self.length];
uint8_t digest[CC_SHA384_DIGEST_LENGTH];
CC_SHA384(data.bytes, data.length, digest);
NSMutableString* output = [NSMutableString stringWithCapacity:CC_SHA384_DIGEST_LENGTH * 2];
for(int i = 0; i < CC_SHA384_DIGEST_LENGTH; i++)
[output appendFormat:@"%02x", digest[i]];
return output;
}
- (NSString*) sha512
{
const char *cstr = [self cStringUsingEncoding:NSUTF8StringEncoding];
NSData *data = [NSData dataWithBytes:cstr length:self.length];
uint8_t digest[CC_SHA512_DIGEST_LENGTH];
CC_SHA512(data.bytes, data.length, digest);
NSMutableString* output = [NSMutableString stringWithCapacity:CC_SHA512_DIGEST_LENGTH * 2];
for(int i = 0; i < CC_SHA512_DIGEST_LENGTH; i++)
[output appendFormat:@"%02x", digest[i]];
return output;
}