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

1.1 单向散列函数

单向散列函数(One-way hash function),也称之为消息摘要函数(Message Digest Function),哈希函数,它可以根据消息的内容计算出一个散列值;
输出的散列值,也被称为消息摘要(message digest)、指纹(fingerprint);

1.2 单向散列函数的特点

1.散列值的长度与消息的长度<mark>无关</mark>,无论消息是1bit、10M、100G,单向散列函数都会计算出<mark>固定长度</mark>的散列值,如下图:

单向散列函数

2.计算速度快,能快速的计算出散列值;

3.消息不同,散列值也不同;

4.具备单向性:无法通过散列值反推出原始消息内容

单向性

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 <CommonCrypto/CommonDigest.h>
@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 = [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;
}

-(NSString *)sha224String{
    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, (unsigned int)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 *)sha256String{
    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,(CC_LONG)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 *)sha384String
{
    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,(CC_LONG) 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 *)sha512String
{
    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, (CC_LONG)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;
}

3 单向散列函数的应用

3.1 某些大型软件的官网会公布软件的散列值,防止软件被篡改

软件生成散列值防伪

例如: vnc官网下载链接,会有软件的SHA256生成的散列值:

vnc官网软件散列值示例

3.2 服务器存放的用户的密码不是明文的,而是对应密码的散列值,比如SHA2(密码)

用户密码服务端存放示例

服务器中存放的不是用户密码的明文,如果存放的是密码明文,风险太高,一般存放的是对应用户名的密码的散列值,在用户登录的时候,通过散列值与数据库中的散列值对比,如果相同则登录成功.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,137评论 6 511
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,824评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,465评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,131评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,140评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,895评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,535评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,435评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,952评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,081评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,210评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,896评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,552评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,089评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,198评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,531评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,209评论 2 357