iOS 关于CommonCrypto 框架③(MD5、SHA1以及HMAC_SHA1 等哈希摘要)

在上一部分iOS 关于CommonCrypto框架 ②(CommonCryptor AES|DES|3DES|CAST|BlowFish)中介绍了AES|DES|3DES|CAST|BlowFish等对称加密算法相关的内容,接下来就是 以及文件了。

之前在概述中说过,文件中包含了MD5,SHA1,SHA256等哈希摘要算法的接口,我们可以使用它去对数据进行哈希摘要,而文件中则是有关HMAC的接口文档了。

简单的介绍一下 Hash 以 HMAC.

Hash

Hash,一般翻译做“散列”,也有直接音译为”哈希”的,就是把任意长度的输入(又叫做预映射,pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值。
Hash算法在信息安全方面的应用主要体现在以下的3个方面:

  1. 文件校验
  2. 数字签名
  3. 鉴权协议

HMAC介绍

HMAC运算利用哈希算法,以一个密钥和一个消息为输入,生成一个消息摘要作为输出。”
HMAC主要应用在身份验证中,它的使用方法是这样的:

  1. 客户端发出登录请求(假设是浏览器的GET请求)
  2. 服务器返回一个随机值,并在会话中记录这个随机值
  3. 客户端将该随机值作为密钥,用户密码进行hmac运算,然后提交给服务器.
  4. 服务器读取用户数据库中的用户密码和步骤2中发送的随机值做与客户端一样的hmac运算,然后与用户发送的结果比较,如果结果一致则验证用户合法。

Digest 代码部分

CommonDigest中苹果说明 有关 *Init(), *Update(),
*Final() 的函数已经被弃用了,我们可以直接使用类似于CC_MD2(), CC_SHA1()这样的函数进行摘要。
例如

  • MD5
- (NSData *)md5Data
{
    unsigned char hash[CC_MD5_DIGEST_LENGTH];
    (void) CC_MD5( [self bytes], (CC_LONG)[self length], hash );
    return ( [NSData dataWithBytes: hash length: CC_MD5_DIGEST_LENGTH] );
}
- (NSString *)md5String {
    unsigned char result[CC_MD5_DIGEST_LENGTH];
    CC_MD5(self.bytes, (CC_LONG)self.length, result);
    NSMutableString *hash = [NSMutableString
                             stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
    for (int i = 0; i < CC_MD5_DIGEST_LENGTH; i++) {
        [hash appendFormat:@"%02x", result[i]];
    }
    return hash;
}
  • SHA1
- (NSData *)sha1Data
{
    unsigned char hash[CC_SHA1_DIGEST_LENGTH];
    (void) CC_SHA1( [self bytes], (CC_LONG)[self length], hash );
    return ( [NSData dataWithBytes: hash length: CC_SHA1_DIGEST_LENGTH] );
}
- (NSString *)sha1String {
    unsigned char result[CC_SHA1_DIGEST_LENGTH];
    CC_SHA1(self.bytes, (CC_LONG)self.length, result);
    NSMutableString *hash = [NSMutableString
                             stringWithCapacity:CC_SHA1_DIGEST_LENGTH * 2];
    for (int i = 0; i < CC_SHA1_DIGEST_LENGTH; i++) {
        [hash appendFormat:@"%02x", result[i]];
    }
    return hash;
}

我们可以发现像MD2,MD4,MD5,SHA1,SHA224,SHA256,SHA384,SHA512这些摘要算法都是三步就可以获取到摘要后的数据或者字符串。

  1. 声明一个相应摘要算法长度的无符号字节数组.
  2. 通过相应函数,例如CC_SHA1(),传入对应参数:需要摘要的字节数组,需要摘要的数据长度以及 传入获取结果的字节数组
    3.转换为NSData或者NSString类型数据.

HMAC代码部分

接下来看CommonHMAC文件,分为三个部分

  • HMAC算法的枚举
enum {
    kCCHmacAlgSHA1,
    kCCHmacAlgMD5,
    kCCHmacAlgSHA256,
    kCCHmacAlgSHA384,
    kCCHmacAlgSHA512,
    kCCHmacAlgSHA224
};
typedef uint32_t CCHmacAlgorithm;
  • CCHmacInit()、CCHmacUpdate()、CCHmacFinal()函数.
  • CCHmac()函数.
    其实我们实现普通的HMAC密匙消息认证,只需要CCHmacAlgorithmCCHmac()函数就可以了,实现代码部分:
- (NSData *)hmacDataUsingAlg:(CCHmacAlgorithm)alg withKey:(id)key {
    NSParameterAssert([key isKindOfClass: [NSData class]] || [key isKindOfClass: [NSString class]]);
    size_t size;
    switch (alg) {
        case kCCHmacAlgMD5: size = CC_MD5_DIGEST_LENGTH; break;
        case kCCHmacAlgSHA1: size = CC_SHA1_DIGEST_LENGTH; break;
        case kCCHmacAlgSHA224: size = CC_SHA224_DIGEST_LENGTH; break;
        case kCCHmacAlgSHA256: size = CC_SHA256_DIGEST_LENGTH; break;
        case kCCHmacAlgSHA384: size = CC_SHA384_DIGEST_LENGTH; break;
        case kCCHmacAlgSHA512: size = CC_SHA512_DIGEST_LENGTH; break;
        default: return nil;
    }
    NSMutableData * keyData;
    if ( [key isKindOfClass: [NSData class]] )
        keyData = (NSMutableData *) [key mutableCopy];
    else
        keyData = [[key dataUsingEncoding: NSUTF8StringEncoding] mutableCopy];
    
    unsigned char result[size];
    CCHmac(alg, [keyData bytes], keyData.length, self.bytes, self.length, result);
    return [NSData dataWithBytes:result length:size];
}

我们只需要通过传入算法参数就可以完成对应的密钥消息认证, 例如传入kCCHmacAlgMD5就是HMAC+MD5

关于哈希摘要就说这么多了,全部代码可以从Github下载。

你可能感兴趣的:(iOS 关于CommonCrypto 框架③(MD5、SHA1以及HMAC_SHA1 等哈希摘要))