美文网首页
iOS开发单向散列函数:MD5及SHA1-SHA224-SHA2

iOS开发单向散列函数:MD5及SHA1-SHA224-SHA2

作者: YYFast | 来源:发表于2019-11-26 22:22 被阅读0次

    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(密码)

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

    相关文章

      网友评论

          本文标题:iOS开发单向散列函数:MD5及SHA1-SHA224-SHA2

          本文链接:https://www.haomeiwen.com/subject/gbskwctx.html