完整文章列表:
iOS的签名与证书机制(一):加密解密
iOS的签名与证书机制(二):单向散列函数
iOS的签名与证书机制(三):数字签名与证书
iOS的签名与证书机制(四):iOS的签名
单向散列函数(One-way hash function),也称之为消息摘要函数(Message Digest Function),哈希函数,它可以根据消息的内容计算出一个散列值,这个散列值,我们可以看做是这个消息的数字指纹,而且不管消息的内容多少,小到几个字节,大到你珍藏多年的学习资料,都会被压缩为一段固定长度的散列值,这是一个有损压缩的过程.
之所以要学习单向散列函数,是为了下一章的数字签名打下基础;
翠花继续上图:
我们来看看单向散列函数的特点:
- 任意长度的信息,计算出固定的散列值;
- 单向性,即不可逆性,从散列值不能计算出原有的消息,不过对于MD5以及SHA-1算法,目前证明可以被破解,这里要介绍一下王小云教授,带领中国团队破解了这两种算法;
- 如果明文不一样,那么散列后的结果一定不一样;
- 如果明文一样,散列后的结果一定一样;
常见的单向散列函数有以下几种:
- MD4,MD5:Message Digest 4(5),产生的是128bit的散列值,目前已经不安全,可以被暴力破解;
在我们的Mac终端,可以直接使用md5命令;
在项目中我们经常使用的是对用户密码等隐私信息进行MD5加密,然后发送到服务器,下面就是我们常用的MD5加密代码
#import <CommonCrypto/CommonCrypto.h>
@implementation NSString (MD5)
#pragma mark - 32位 小写
- (NSString *)MD5ForLower32Bate{
//要进行UTF8的转码
const char* input = [self UTF8String];
unsigned char result[CC_MD5_DIGEST_LENGTH];
CC_MD5(input, (CC_LONG)strlen(input), result);
NSMutableString *digest = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
for (NSInteger i = 0; i < CC_MD5_DIGEST_LENGTH; i++) {
[digest appendFormat:@"%02x", result[i]];
} return digest; }
- SHA-1:Secure Hash Algorithm 1,安全散列算法1,产生160bit的散列值,目前已不安全,下面我也会附上iOS项目中使用该算法加密的代码;
- SHA-2:包括了SHA-256,SHA-384,SHA-512,对应的计算出的散列值长度为256bit,384bit,512bit;
#import <CommonCrypto/CommonDigest.h>
#import <CommonCrypto/CommonHMAC.h>
@implementation NSString (Hash)
- (NSString *)sha1String
{
const char *string = self.UTF8String;
int length = (int)strlen(string);
unsigned char bytes[CC_SHA1_DIGEST_LENGTH];
CC_SHA1(string, length, bytes);
return [self stringFromBytes:bytes length:CC_SHA1_DIGEST_LENGTH];
}
- (NSString *)sha256String
{
const char *string = self.UTF8String;
int length = (int)strlen(string);
unsigned char bytes[CC_SHA256_DIGEST_LENGTH];
CC_SHA256(string, length, bytes);
return [self stringFromBytes:bytes length:CC_SHA256_DIGEST_LENGTH];
}
- (NSString *)sha512String
{
const char *string = self.UTF8String;
int length = (int)strlen(string);
unsigned char bytes[CC_SHA512_DIGEST_LENGTH];
CC_SHA512(string, length, bytes);
return [self stringFromBytes:bytes length:CC_SHA512_DIGEST_LENGTH];
}
- (NSString *)stringFromBytes:(unsigned char *)bytes length:(NSInteger)length
{
NSMutableString *mutableString = @"".mutableCopy;
for (NSInteger i = 0; i < length; i++)
[mutableString appendFormat:@"%02x", bytes[i]];
return [NSString stringWithString:mutableString];
}
- SHA-3:包括了SHA3-256,SHA3-384,SHA3-512,对应的计算出的散列值长度为256bit,384bit,512bit,这也是现在全新的标准;
那么单向散列函数可以应用在哪些方面呢?
-
隐私信息加密传输;
当用户在客户端填写完账号密码向服务器验证的时候,密码绝对不能明文传输,或者说我们在服务器中保存的只是用户密码的哈希值,每次用两个哈希值进行比较;
- 文件识别,防止数据被篡改;
很多unix软件下载的时候,在文件的下载地址下方会有一个散列值,同时还会提供一套计算文件散列值的小工具,当你下载完毕的时候,计算出下载文件的散列值与官方的进行对比,如果一致则说明软件是安全的,没有被篡改过;
比如这个软件:https://www.realvnc.com/en/connect/download/vnc/;
这也正是下一章的数字签名会用到的特性; - 保存文件与图片的唯一性,防止重复下载;
很多App需要从服务器下载图片或者文件,存储在本地的时候,可以用下载地址的md5散列值来作为文件名.下载之前,可以通过下载地址的md5散列值来检查本地是否已经有了该文件,避免重复下载;
看到这里,需要小伙伴记住的是:消息摘要,作为信息的签名和指纹,可以把大量信息压缩为一个固定长度的散列值,可以验证消息是否被篡改;
在下一章的数字签名中,小伙伴就可以看到它的具体应用;