密码学(二)- MD5 & HMAC

一、MD5

MD5加密算法反向查询网站
网站简介:本站针对md5等全球通用公开的加密算法进行反向查询,建立了密文对应查询数据库,很多复杂密文只有本站才可查询,支持多种算法,实时查询记录超过24万亿条,共占用160T硬盘,成功率95%以上,建站11年,国内外享有盛誉。

1.1、MD5用途
  • 1、密码加密
    服务器不需要知道用户的密码,数据库保存的是加密后的数据。
    
  • 2、搜索
    搜索:"iOS 进阶"
    "iOS"的MD5 = 1bdf605991920db11cbdf8508204c4eb
    "进阶"的MD5 = fa11f8c07c1629d5f0ab1cfecdf1f686
    搜索引擎只需要知道关键字的MD5,所以搜索结果相同。
    
  • 3、版权
    原版的MD5是唯一的,其他盗版无论如何逼真MD5都不同;
    测试:截屏相同图片的MD5一定不一样。
    
  • 4、文件完整性校验
    1、下载文件校验,比较MD5是否一致,防止丢包;
    2、上传(断点续传),比较MD5是否一致,防止丢包;
    拓展-断点续传:从服务器获取文件指针,客户端移动文件指针继续上传;
    3、秒传:在服务器对比MD5,如果存在相同,则不需要上传;
    
1.2、MD5加盐
  • (pwd+盐).md5
  • 盐的不足
    • 盐是固定的
    • 盐不能修改
测试:终端输出MD5:`md5 -s "ABC"
终端输出MD5.png

二、HMAC - Hash-based Message Authentication Code

  • HMAC 加密!! 这种加密算法目前非常流行!!而且很多大公司在用!!!
    pwd = [pwd hmacMD5StringWithKey:KEY];
    
  • 在真实的开发中,**这个KEY:从服务器获取!! -- 注册的时候获取
    • 密钥KEY分为两种:1、需要授权;2、直接返回密钥;
    • 授权策略一:通过旧设备允许,返回KEY; (类似QQ授权登录)
    • 授权策略二:没有旧设备了,手机短信验证码允许,返回KEY;
  • 获取密钥KEY立刻保存到本地 -- 钥匙串

代码流程图

//----HMAC----
    NSString *key = nil;
    // 1、从钥匙串获取key,如果不存在,则去服务器要key。如果存在,则直接进行加密。
    if (key == nil) {
        //2、发送网络请求,获取密钥!
        key = [self getKeyWithAccount:user];
        
        //3、展示小菊花
        
        //4、如果是需要授权的话,展示等待授权页面!
        
        //5、服务器返回key,立刻马上保存这个key到本地!!!通过钥匙串访问
        if (key.length > 0 ) {
            // 6、钥匙串保存key
            [SSKeychain setPassword:key forService:CCKeySeviceName account:user];
        }
    }

    // 7、pwd根据获取的Key进行HMAC加密
    pwd = [pwd hmacMD5StringWithKey:key];

    // 8、进行登录请求
    if([self isLoginWithUserId:user password:pwd])
    {
          .......
    }

缺陷:

问题:如果黑客截取了你请求的Http中的 HMAC(pwd+key) 后的结果,完全不需要知道你的key和密码,也能模拟进行网络请求。
解决方案:增加时效性,即:HMAC(pwd+key+当前系统时间),系统做相同处理,这样做的结果:导致当前截取的字段只能短期有效


拓展 -- HMAC注册&&登录分析


注册
  • 向服务器请求一个随机的秘钥
  • 把注册的密码进行 md5.hmac(hamc使用md5的散列函数来操作字符)加密 :
     md5.hmac(key,message) ==> 密文摘要(key : 秘钥 , message : 明文) : md5.hmac密文摘要
    
  • 把摘要提交到服务器,同时服务器把 该秘钥md5.hmac密文摘要 持久化到数据库
登录
  • 客户端向服务器请求秘钥(注册时候存储的秘钥)

  • 在用户提交数据的时候对密码进行加密 :

      md5.hmac(key , pwd) ==> 子摘要 
      md5.hamc(key , (子摘要 + ‘当前提交时间’)) ==> 总摘要
    
  • 当服务器接收到总摘要消息的时候处理流程 :

    • 取出 秘钥 key , 存储的密文摘要 pwdDigest
    • 根据以下公式计算两段密文摘要 :
      md5.hamc(key , '当前提交时间' + pwdDigest) ==>目的摘要1
      md5.hamc(key , '当前提交时间 + 1(分钟)' + pwdDigest) ==>目的摘要2
      
    • 如果用户提交的 总摘要 == 目的摘要1 || 总摘要 == 目的摘要2 为密码正确
这样做的好处
  • 注册只有一次, 提交 关键摘要 的操作只有一次,因此受到拦截数据的几率很少
  • 在登录的时候,由于加密使用了系统时间,因此这样可以保证密码摘要的动态性,而且服务器只会辨认一分钟以内的密文摘要,这样做,就算用户提交数据给拦截了,也很少有时间提供给黑客达到模仿正确登录请求

完!!

本文由lionsom_lin整合编写!!欢迎点赞!!

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容