zoukankan      html  css  js  c++  java
  • Hash函数和消息认证

    转:https://www.cnblogs.com/WittPeng/p/8978737.html

    Hash函数

    定义 是一个从消息空间到像空间不可逆映射,同时是一种具有压缩性的单向函数
    散列值的生成 h=H(M)  h是定长的散列值,H是Hash函数运算,M是一个变成消息
    应用 数字签名  
    消息认证

    生成程序或文档的“数字指纹”

    用于安全运输和存储口令

    性质          生成任意长度的消息  
    产生定长的输出   
    计算任意给定的消息比较容易   
       安全性 单向性:找到H(x)=h的x是不可行的 
    抗弱碰撞性:对于给定的消息M1,要发现另一个消息M2,满足H(M1)=H(M2)在计算上是不可行的
    抗强碰撞性:找任意一对不同的消息M1M2,使H(M1)=H(M2)在计算上是不可行的 

     雪崩效应

     
     单向性  
    用途    生成数字签名Sign(H(M))
    对程序或者文件生成摘要(完整性认证)H(M)  
    口令H(Password)        
    函数结构 核心技术:设计无碰撞的压缩函数f

    迭代结构:

    1.将输入消息分成L个固定长度的分组,每个分组为b位,最后一个分组包含输入消息的总长度,若不足b位需要填充,

    2.压缩函数f:有两个输入,一个是前一次迭代的n位输出,成为链接变量;一个是消息的b位分组,并产生一个n位的输出,即散列值。

    Hash算法

    MD5(128位) 结构
     生成过程  
     主循环      
    每一分组的算法流程如下:
    第一分组需要将上面四个链接变量复制到另外四个变量中:A到a,B到b,C到c,D到d。从第二分组开始的变量为上一分组的运算结果,即A = a, B = b, C = c, D = d。
    主循环有四轮(MD4只有三轮),每轮循环都很相似。第一轮进行16次操作。每次操作对a、b、c和d中的其中三个作一次非线性函数运算,然后将所得结果加上第四个变量,
    文本的一个子分组和一个常数。再将所得结果向左环移一个不定的数,并加上a、b、c或d中之一。最后用该结果取代a、b、c或d中之一。
    以下是每次操作中用到的四个非线性函数(每轮一个)。
    F( X ,Y ,Z ) = ( X & Y ) | ( (~X) & Z )
    G( X ,Y ,Z ) = ( X & Z ) | ( Y & (~Z) )
    H( X ,Y ,Z ) =X ^ Y ^ Z
    I( X ,Y ,Z ) =Y ^ ( X | (~Z) )
    (&是与(And),|是或(Or),~是非(Not),^是异或(Xor))
    这四个函数的说明:如果X、Y和Z的对应位是独立和均匀的,那么结果的每一位也应是独立和均匀的。
    F是一个逐位运算的函数。即,如果X,那么Y,否则Z。函数H是逐位奇偶操作符。
    假设Mj表示消息的第j个子分组(从0到15),常数ti是4294967296*abs( sin(i) )的整数部分,i 取值从1到64,单位是弧度。(4294967296=232)
    现定义:
    FF(a ,b ,c ,d ,Mj ,s ,ti ) 操作为 a = b + ( (a + F(b,c,d) + Mj + ti) << s)
    GG(a ,b ,c ,d ,Mj ,s ,ti ) 操作为 a = b + ( (a + G(b,c,d) + Mj + ti) << s)
    HH(a ,b ,c ,d ,Mj ,s ,ti) 操作为 a = b + ( (a + H(b,c,d) + Mj + ti) << s)
    II(a ,b ,c ,d ,Mj ,s ,ti) 操作为 a = b + ( (a + I(b,c,d) + Mj + ti) << s)
    注意:“<<”表示循环左移位,不是左移位。
    这四轮(共64步)是:
    第一轮
    FF(a ,b ,c ,d ,M0 ,7 ,0xd76aa478 )
    FF(d ,a ,b ,c ,M1 ,12 ,0xe8c7b756 )
    FF(c ,d ,a ,b ,M2 ,17 ,0x242070db )
    FF(b ,c ,d ,a ,M3 ,22 ,0xc1bdceee )
    FF(a ,b ,c ,d ,M4 ,7 ,0xf57c0faf )
    FF(d ,a ,b ,c ,M5 ,12 ,0x4787c62a )
    FF(c ,d ,a ,b ,M6 ,17 ,0xa8304613 )
    FF(b ,c ,d ,a ,M7 ,22 ,0xfd469501)
    FF(a ,b ,c ,d ,M8 ,7 ,0x698098d8 )
    FF(d ,a ,b ,c ,M9 ,12 ,0x8b44f7af )
    FF(c ,d ,a ,b ,M10 ,17 ,0xffff5bb1 )
    FF(b ,c ,d ,a ,M11 ,22 ,0x895cd7be )
    FF(a ,b ,c ,d ,M12 ,7 ,0x6b901122 )
    FF(d ,a ,b ,c ,M13 ,12 ,0xfd987193 )
    FF(c ,d ,a ,b ,M14 ,17 ,0xa679438e )
    FF(b ,c ,d ,a ,M15 ,22 ,0x49b40821 )
    第二轮
    GG(a ,b ,c ,d ,M1 ,5 ,0xf61e2562 )
    GG(d ,a ,b ,c ,M6 ,9 ,0xc040b340 )
    GG(c ,d ,a ,b ,M11 ,14 ,0x265e5a51 )
    GG(b ,c ,d ,a ,M0 ,20 ,0xe9b6c7aa )
    GG(a ,b ,c ,d ,M5 ,5 ,0xd62f105d )
    GG(d ,a ,b ,c ,M10 ,9 ,0x02441453 )
    GG(c ,d ,a ,b ,M15 ,14 ,0xd8a1e681 )
    GG(b ,c ,d ,a ,M4 ,20 ,0xe7d3fbc8 )
    GG(a ,b ,c ,d ,M9 ,5 ,0x21e1cde6 )
    GG(d ,a ,b ,c ,M14 ,9 ,0xc33707d6 )
    GG(c ,d ,a ,b ,M3 ,14 ,0xf4d50d87 )
    GG(b ,c ,d ,a ,M8 ,20 ,0x455a14ed )
    GG(a ,b ,c ,d ,M13 ,5 ,0xa9e3e905 )
    GG(d ,a ,b ,c ,M2 ,9 ,0xfcefa3f8 )
    GG(c ,d ,a ,b ,M7 ,14 ,0x676f02d9 )
    GG(b ,c ,d ,a ,M12 ,20 ,0x8d2a4c8a )
    第三轮
    HH(a ,b ,c ,d ,M5 ,4 ,0xfffa3942 )
    HH(d ,a ,b ,c ,M8 ,11 ,0x8771f681 )
    HH(c ,d ,a ,b ,M11 ,16 ,0x6d9d6122 )
    HH(b ,c ,d ,a ,M14 ,23 ,0xfde5380c )
    HH(a ,b ,c ,d ,M1 ,4 ,0xa4beea44 )
    HH(d ,a ,b ,c ,M4 ,11 ,0x4bdecfa9 )
    HH(c ,d ,a ,b ,M7 ,16 ,0xf6bb4b60 )
    HH(b ,c ,d ,a ,M10 ,23 ,0xbebfbc70 )
    HH(a ,b ,c ,d ,M13 ,4 ,0x289b7ec6 )
    HH(d ,a ,b ,c ,M0 ,11 ,0xeaa127fa )
    HH(c ,d ,a ,b ,M3 ,16 ,0xd4ef3085 )
    HH(b ,c ,d ,a ,M6 ,23 ,0x04881d05 )
    HH(a ,b ,c ,d ,M9 ,4 ,0xd9d4d039 )
    HH(d ,a ,b ,c ,M12 ,11 ,0xe6db99e5 )
    HH(c ,d ,a ,b ,M15 ,16 ,0x1fa27cf8 )
    HH(b ,c ,d ,a ,M2 ,23 ,0xc4ac5665 )
    第四轮
    II(a ,b ,c ,d ,M0 ,6 ,0xf4292244 )
    II(d ,a ,b ,c ,M7 ,10 ,0x432aff97 )
    II(c ,d ,a ,b ,M14 ,15 ,0xab9423a7 )
    II(b ,c ,d ,a ,M5 ,21 ,0xfc93a039 )
    II(a ,b ,c ,d ,M12 ,6 ,0x655b59c3 )
    II(d ,a ,b ,c ,M3 ,10 ,0x8f0ccc92 )
    II(c ,d ,a ,b ,M10 ,15 ,0xffeff47d )
    II(b ,c ,d ,a ,M1 ,21 ,0x85845dd1 )
    II(a ,b ,c ,d ,M8 ,6 ,0x6fa87e4f )
    II(d ,a ,b ,c ,M15 ,10 ,0xfe2ce6e0 )
    II(c ,d ,a ,b ,M6 ,15 ,0xa3014314 )
    II(b ,c ,d ,a ,M13 ,21 ,0x4e0811a1 )
    II(a ,b ,c ,d ,M4 ,6 ,0xf7537e82 )
    II(d ,a ,b ,c ,M11 ,10 ,0xbd3af235 )
    II(c ,d ,a ,b ,M2 ,15 ,0x2ad7d2bb )
    II(b ,c ,d ,a ,M9 ,21 ,0xeb86d391 )
    所有这些完成之后,将a、b、c、d分别在原来基础上再加上A、B、C、D。
    即a = a + A,b = b + B,c = c + C,d = d + D
    然后用下一分组数据继续运行以上算法。
         
         
     SHA-1(160位)  美国国家标准技术研究所NIST开发  
    1、将消息摘要转换成位字符串
    因为在Sha-1算法中,它的输入必须为位,所以我们首先要将其转化为位字符串,我们以“abc”字符串来说明问题,因为'a'=97, 'b'=98, 'c'=99,所以将其转换为位串后为:
    01100001 01100010 01100011
    2、对转换后的位字符串进行补位操作
    Sha-1算法标准规定,必须对消息摘要进行补位操作,即将输入的数据进行填充,使得数据长度对512求余的结果为448,填充比特位的最高位补一个1,其余的位补0,如果在补位之前已经满足对512取模余数为448,也要进行补位,在其后补一位1即可。总之,补位是至少补一位,最多补512位,我们依然以“abc”为例,其补位过程如下:
    初始的信息摘要:01100001 01100010 01100011
    第一步补位:    01100001 01100010 01100011 1
    ..... ......
    补位最后一位:  01100001 01100010 01100011 10.......0(后面补了423个0)
    而后我们将补位操作后的信息摘要转换为十六进制,如下所示:
    61626380 00000000 00000000 00000000
    00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000
    00000000 00000000
    3、附加长度值
    在信息摘要后面附加64bit的信息,用来表示原始信息摘要的长度,在这步操作之后,信息报文便是512bit的倍数。通常来说用一个64位的数据表示原始消息的长度,如果消息长度不大于2^64,那么前32bit就为0,在进行附加长度值操作后,其“abc”数据报文即变成如下形式:
    61626380 00000000 00000000 00000000
    00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000018
    因为“abc”占3个字节,即24位 ,换算为十六进制即为0x18。
    4、初始化缓存
    一个160位MD缓冲区用以保存中间和最终散列函数的结果。它可以表示为5个32位的寄存器(H0,H1,H2,H3,H4)。初始化为:
    H0 = 0x67452301
    H1 = 0xEFCDAB89
    H2 = 0x98BADCFE
    H3 = 0x10325476
    H4 = 0xC3D2E1F0
    如果大家对MD-5不陌生的话,会发现一个重要的现象,其前四个与MD-5一样,但不同之处为存储为big-endien format.
    5、计算消息摘要
    在计算报文之前我们还要做一些基本的工作,就是在我们计算过程中要用到的方法,或定义。
    (1)、循环左移操作符Sn(x),x是一个字,也就是32bit大小的变量,n是一个整数且0<=n<=32。Sn(X) = (X<<n)OR(X>>32-n)
    (2)、在程序中所要用到的常量,这一系列常量字k(0)、k(1)、...k(79),将其以十六进制表示如下:
    Kt = 0x5A827999  (0 <= t <= 19)
    Kt = 0x6ED9EBA1 (20 <= t <= 39)
    Kt = 0x8F1BBCDC (40 <= t <= 59)
    Kt = 0xCA62C1D6 (60 <= t <= 79)
    (3)、所要用到的一系列函数
     Ft(b,c,d)  ((b&c)|((~b)&d))    (0 <= t <= 19)
     Ft(b,c,d) (b^c^d)             (20 <= t <= 39)
     Ft(b,c,d) ((b&c)|(b&d)|(c&d))  (40 <= t <= 59)
     Ft(b,c,d) (b^c^d)               (60 <= t <= 79)
    (4)、计算
    计算需要一个缓冲区,由5个32位的字组成,还需要一个80个32位字的缓冲区。第一个5个字的缓冲区被标识为A,B,C,D,E。80个字的缓冲区被标识为W0, W1,..., W79
    另外还需要一个一个字的TEMP缓冲区。
    为了产生消息摘要,在第4部分中定义的16个字的数据块M1, M2,..., Mn
    会依次进行处理,处理每个数据块Mi 包含80个步骤。
    现在开始处理M1, M2, ... , Mn。为了处理 Mi,需要进行下面的步骤
    (1). 将 Mi 分成 16 个字 W0, W1, ... , W15,  W0 是最左边的字
    (2). 对于 t = 16 到 79 令 Wt = S1(Wt-3 XOR Wt-8 XOR Wt- 14 XOR Wt-16).
    (3). 令 A = H0, B = H1, C = H2, D = H3, E = H4.
    (4) 对于 t = 0 到 79,执行下面的循环
    TEMP = S5(A) + ft(B,C,D) + E + Wt + Kt;
    E = D; D = C; C = S30(B); B = A; A = TEMP;
    (5). 令 H0 = H0 + A, H1 = H1 + B, H2 = H2 + C, H3 = H3 + D, H4 = H4 + E. 
    在处理完所有的 Mn, 后,消息摘要是一个160位的字符串,以下面的顺序标识
    H0 H1 H2 H3 H4.
    对于SHA256,SHA384,SHA512。你也可以用相似的办法来计算消息摘要。对消息进行补位的算法完全是一样的。

    Hash函数的攻击

    生日攻击:p(k)=1-p365k/365k;k=23,p(k)=0.5073;k=100,p(k)=0.99999997。可以减少一半的尝试量

    两个集合的相交问题。

    Hash函数的应用

    消息认证:

    目的:

      1. 验证是否真实
      2. 验证完整性

    MDC和加密:仅能验证完整性

    消息认证码MAC

      • 用于消息源认证和消息完整性的认证
      • 构造MAC的方法
        1. 使用DES分组加密算法的MAC
        2. 基于Hash的认证码——HMAC

          • 安全性:包里搜索密钥需要2k(k为密钥长度);攻击MAC需要2n
  • 相关阅读:
    从Java角度理解Angular之入门篇:npm, yarn, Angular CLI
    大数据开发实战:Stream SQL实时开发一
    大数据开发实战:Spark Streaming流计算开发
    大数据开发实战:Storm流计算开发
    大数据开发实战:Hadoop数据仓库开发实战
    数据仓库中的拉链表
    java通过jdbc连接impala
    impala-shell常用命令
    Kudu-java数据库简单操作
    拉链表--实现、更新及回滚的具体实现( 转载)
  • 原文地址:https://www.cnblogs.com/69-year-old-comrade/p/15313731.html
Copyright © 2011-2022 走看看