iOS开发单向散列函数:MD5及SHA1-SHA224-SHA256-SHA384-SHA512

1.1 单向散列函数 单向散列函数(One-way hash function),也称之为消息摘要函数(Message Digest Function),哈希函数,它可以根据消息的内容计算出一个散列值;
输出的散列值,也被称为消息摘要(message digest)、指纹(fingerprint);
1.2 单向散列函数的特点 1.散列值的长度与消息的长度无关,无论消息是1bit、10M、100G,单向散列函数都会计算出固定长度的散列值,如下图:
iOS开发单向散列函数:MD5及SHA1-SHA224-SHA256-SHA384-SHA512
文章图片
单向散列函数 【iOS开发单向散列函数:MD5及SHA1-SHA224-SHA256-SHA384-SHA512】2.计算速度快,能快速的计算出散列值;
3.消息不同,散列值也不同;
4.具备单向性:无法通过散列值反推出原始消息内容
iOS开发单向散列函数:MD5及SHA1-SHA224-SHA256-SHA384-SHA512
文章图片
单向性 2.1 单向散列函数常见类型 ·MD4:具有3轮16步,输出位长度为128位。
·MD5:具有4轮16步,输出位长128位。
·SHA-1:具有4个20阶的步长和160位的输出位长度。
·SHA-256:具有64轮单步,输出位长度为256位。
·SHA-384:实际上与SHA-512相同,除了输出被截断为383位。
·SHA-512:具有80个单步的轮数和512位的输出位长度。
2.1.1 MD4:
MD4(RFC 1320)是 MIT 的 Ronald L. Rivest 在 1990 年设计的,MD 是 Message Digest 的缩写。它适用在32位字长的处理器上用高速软件实现--它是基于 32 位操作数的位操作来实现的。它的安全性不像RSA那样基于数学假设,尽管 Den Boer、Bosselaers 和 Dobbertin 很快就用分析和差分成功的攻击了它3轮变换中的 2 轮,证明了它并不像期望的那样安全,但它的整个算法并没有真正被破解过,Rivest 也很快进行了改进。
2.1.2 MD5:
MD5(RFC 1321)是 Rivest 于1991年对MD4的改进版本。它对输入仍以512位分组,其输出是4个32位字的级联,与 MD4 相同。它较MD4所做的改进是:

  1. 加入了第四轮
  2. 每一步都有唯一的加法常数;
  3. 第二轮中的G函数从((X ∧ Y) ∨ (X ∧ Z) ∨ (Y ∧ Z)) 变为 ((X ∧ Z) ∨ (Y ∧ ~Z))以减小其对称性;
  4. 每一步都加入了前一步的结果,以加快"雪崩效应";
  5. 改变了第2轮和第3轮中访问输入子分组的顺序,减小了形式的相似程度;
  6. 近似优化了每轮的循环左移位移量,以期加快"雪崩效应",各轮的循环左移都不同。
    尽管MD5比MD4来得复杂,并且速度较之要慢一点,但更安全,在抗分析和抗差分方面表现更好。
使用终端查看字符串或者文件的MD5值:
md5 -s 字符串
md5 文件路径
//字符串 md5 -s 24324 MD5 ("24324") = fb2e636577105f243646d6f1e199f0ba//文件 MD5 /Users/i/Desktop/2.pdf MD5 (/Users/i/Desktop/2.pdf) = bd32d590689394cae6a3f234a33ca93c

iOS实现字符串转MD5:
#import "NSString+MD5.h" @implementation NSString (MD5)- (NSString *)MD5String{ //传入参数,转化成char const char * str = [self UTF8String]; //开辟一个16字节(128位:md5加密出来就是128位/bit)的空间(一个字节=8字位=8个二进制数) unsigned char md[CC_MD5_DIGEST_LENGTH]; /* extern unsigned char * CC_MD5(const void *data, CC_LONG len, unsigned char *md)官方封装好的加密方法 把str字符串转换成了32位的16进制数列(这个过程不可逆转) 存储到了md这个空间中 */ CC_MD5(str, (int)strlen(str), md); //创建一个可变字符串收集结果 NSMutableString * ret = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH]; for (int i = 0; i < CC_MD5_DIGEST_LENGTH; i++) { /** X 表示以十六进制形式输入/输出 02 表示不足两位,前面补0输出;出过两位不影响 printf("%02X", 0x123); //打印出:123 printf("%02X", 0x1); //打印出:01 */ [ret appendFormat:@"%02X",md[i]]; } //返回一个长度为32的字符串 return ret; } @end

ios实现NSData转H5
#import "NSData+MD5.h" #import @implementation NSData (MD5) -(NSData *)MD5Data{ unsigned char result[CC_MD5_DIGEST_LENGTH]; CC_MD5(self.bytes, (CC_LONG)self.length, result); return [NSData dataWithBytes:result length:CC_MD5_DIGEST_LENGTH]; } @end

2.1.3 SHA1-SHA224-SHA256-SHA384-SHA512:
- (NSString *) sha1String{ NSData *data = https://www.it610.com/article/[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

3 单向散列函数的应用 3.1 某些大型软件的官网会公布软件的散列值,防止软件被篡改
iOS开发单向散列函数:MD5及SHA1-SHA224-SHA256-SHA384-SHA512
文章图片
软件生成散列值防伪 例如: vnc官网下载链接,会有软件的SHA256生成的散列值:

iOS开发单向散列函数:MD5及SHA1-SHA224-SHA256-SHA384-SHA512
文章图片
vnc官网软件散列值示例
3.2 服务器存放的用户的密码不是明文的,而是对应密码的散列值,比如SHA2(密码)

iOS开发单向散列函数:MD5及SHA1-SHA224-SHA256-SHA384-SHA512
文章图片
用户密码服务端存放示例
服务器中存放的不是用户密码的明文,如果存放的是密码明文,风险太高,一般存放的是对应用户名的密码的散列值,在用户登录的时候,通过散列值与数据库中的散列值对比,如果相同则登录成功.

    推荐阅读