给你的哈希算法加点“盐”

我们在平常的开发过程中为了保证信息的完整性以及安全性,我们通常都会对信息进行哈希计算签名,然后比对签名信息。

但是黑客可以通过彩虹表反推原始输入,为了增加黑客的破解难度,我们会对原始输入做一些处理,通常的做法是加入另外一个输入(也就是盐)混淆,以sha1为例,大概是sha1(message+salt)这个样子。

注:message+salt并不是表示字符串拼接,是表示经过特定的计算或者字符组合。

Hmac算法(Keyed-Hashing for Message Authentication)是一个将盐加入哈希计算的标准算法,它会在计算过程中将salt混入计算过程中,而且它针对所有的哈希算法都通用,相比较我们自己的实现更标准也更安全。

系统也为我们提供了相关API,我们仍以sha1算法为例,不加盐的调用如下:

#import "NSString+Encryption.h"

#import <CommonCrypto/CommonDigest.h>
#import <CommonCrypto/CommonHMAC.h>

- (NSString *)sha1
{
    NSData *data = [self dataUsingEncoding:NSUTF8StringEncoding];
    uint8_t digest[CC_SHA1_DIGEST_LENGTH];
    CC_SHA1(data.bytes, (unsigned int)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;
}

加盐的调用如下:

#import "NSString+Encryption.h"

#import <CommonCrypto/CommonDigest.h>
#import <CommonCrypto/CommonHMAC.h>

- (NSString *)hmacSha1:(NSString *)key
{
    NSData *data = [self dataUsingEncoding:NSUTF8StringEncoding];
    const char *cKey = [key cStringUsingEncoding:NSUTF8StringEncoding];

    unsigned char *digest = malloc(CC_SHA1_DIGEST_LENGTH);
    CCHmac(kCCHmacAlgSHA1, cKey, strlen(cKey), [data bytes], [data length], digest);

    NSData *desData = [NSData dataWithBytes:digest length:CC_SHA1_DIGEST_LENGTH];
    return [desData base64EncodedStringWithOptions:0];
}

其他的算法也可以找到相关的API,这里就不再赘述了。