MD5
首先,我们简单介绍一下MD5(Message Digest Algorithm MD5)。
发展历史
从1989年的MD2->1990年MD4->1991年MD5
应用
- 一致性校验
- 数字签名
- 安全访问认证
一致性验证:unix下有些文件会有一个.md5的文件,它就是对文件的一个签名,用来保证这个文件是否被篡改过。由于不同的内容经过MD5后会产生不同的结果,所以可以保证文件的一致性。利用MD5算法来进行文件的校验被大量应用到软件下载、论坛数据库、系统文件安全等方面。
数字签名:对消息进行加密,消息内容被修改后,重新获取的MD5值就会不一致,如果有第三发进行认证的话,这样就会对文件的消息来源进行保证,防止文件的作者“抵赖”。
安全访问认证:在系统的开发中会经常用到密码的保存。当用户登录时对密码进行MD5加密,然后与数据库的密码进行比对,一致即可完成登录。但是现在通过跑字典的方式可以将MD5加密后的内容还原为加密前的内容。
算法原理
MD5是输入不定长度信息,输出固定的128-bits的算法。经过程序流程,生成四个32位数据,最后连在一起成为一个128-bits散列。基本方式为,求余、取余、调整长度、与链接变量进行循环运算,得到结果。
处理原文
首先计算出原文长度(bit)对512求余,如果不等于448,进行填充原文使得原文对515的求余满足等于448。填充的方式是第一位填充1,其余位填0.填完后,信息的长度为512*N+448。
之后,用剩余的位置(512-448=64位)记录原文的真正长度,把长度的二进制值补在最后。这样处理后的信息长度就是512*(N+1)。
设置初始值
MD5的哈希结果长度为128位,按每32位分成一组工4组。这4组的结果是由4个初始值A、B、C、D经过不断演变得到的。MD5的官方实现中,A、B、C、D的初始值如下(16进制)
1
2
3
4A=0x01234567
B=0x89ABCDEF
C=0xFEDCBA98
D=0x76543210循环加工
我们先看下面的这张图
图中,A、B、C、D就是哈希值的四个分组。每一次循环都会让旧的ABCD产生新的ABCD。循环的次数是由处理后的原文长度决定的。
假设处理后的原文长度为M
主循环次数=M/512
每个主循环中包含512/32 * 4 = 64次子循环。上图为单词子循环的流程。
每次操作对a、b、c和d中的其中三个作一次非线性函数运算,然后将所得结果加上第四个变量,文本的一个子分组和一个常数。再将所得结果向左环移一个不定的数,并加上a、b、c或d中之一。最后用该结果取代a、b、c或d中之一。
现在对图中的元素进行解释
绿色F
图中绿色F,代表非线性函数。MD5所用到的函数有四种:
1
2
3
4F(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))在主循环下面64次子循环中,F、G、H、I 交替使用,第一个16次使用F,第二个16次使用G,第三个16次使用H,第四个16次使用I。
红色田字
红色的田字代表相加的意思
Mi
Mi是第一步处理后的原文。在第一步中,处理后的原文长度为512的整数倍。把原文的没512位在分成16等份,命名为M0~M15,每份长度为32。在64次子循环中,每16次循环,都会交替用到M1~M16之一。
Ki
一个常量,在64次子循环中,每一次用到的常量都是不同的。
黄色的<<
1 | 第一轮: |
拼接结果
循环加工最终产生的A,B,C,D四个值拼接在一起,转换成字符串即可
java实现
1 | package top.wsylp.demo; |
MD5使用很简单:
1 | package top.wsylp.demo; |
SHA1
SHA算法,即安全散列算法(Secure Hash Algorithm)是一种与MD5同源的数据加密算法,该算法经过加密专家多年来的发展和改进已日益完善,现在已成为公认的最安全的散列算法之一,并被广泛使用。
概述
SHA算法能计算出一个数位信息所对应到的,长度固定的字串,又称信息摘要。而且如果输入信息有任何的不同,输出的对应摘要不同的机率非常高。因此SHA算法也是FIPS所认证的五种安全杂凑算法之一。原因有两点:一是由信息摘要反推原输入信息,从计算理论上来说是极为困难的;二是,想要找到两组不同的输入信息发生信息摘要碰撞的几率,从计算理论上来说是非常小的。任何对输入信息的变动,都有很高的几率导致的信息摘要大相径庭。
SHA实际上是一系列算法的统称,分别包括:SHA-1、SHA-224、SHA-256、SHA-384以及SHA-512。后面4中统称为SHA-2,事实上SHA-224是SHA-256的缩减版,SHA-384是SHA-512的缩减版。各中SHA算法的数据比较如下表,其中的长度单位均为位:
类别 | SHA-1 | SHA-224 | SHA-256 | SHA-384 | SHA-512 |
---|---|---|---|---|---|
消息摘要长度 | 160 | 224 | 256 | 384 | 512 |
消息长度 | 小于(2的64幂)位 | 小于(2的64幂)位 | 小于(2的64幂)位 | 小于(2的128幂)位 | 小于(2的128幂)位 |
分组长度 | 512 | 512 | 512 | 1024 | 1024 |
计算字长度 | 32 | 32 | 32 | 64 | 64 |
计算步骤数 | 80 | 64 | 64 | 80 | 80 |
SHA-1在许多安全协定中广为使用,包括TLS和SSL、PGP、SSH、S/MIME和IPsec,曾被视为是MD5的后继者。SHA1主要适用于数字签名标准(Digital Signature Standard DSS)里面定义的数字签名算法(Digital Signature Algorithm DSA)。对于长度小于264位的消息,SHA1会产生一个160位的消息摘要。
基本原理
我们分析SHA-1的算法原理。SHA-1是一种数字加密算法,该算法的思想是接受一段明文,然后以一种不可逆的方式将它转换为一段密文,将不定长读的信息加密为固定长度的散列值,也称之为信息摘要或信息认证过程。
SHA-1算法输入报文的最大长度不超过264位,产生的输出是一个160位的报文摘要。输入是按512 位的分组进行处理的。SHA-1是不可逆的、防冲突,并具有良好的雪崩效应。
对输入信息进行处理
对信息处理的方式与MD5的有些类似,对输入信息按512位进行分组并进行填充。填充后的长度与512进行相除,得到的余数为448位。填充的内容是什么?现在报文的后面加一个1,在加多个0,直到长度满足对512取余的模为448。至于为什么是448位?与MD5类似,会在后面补充64的长度信息。
在上面的报表中,消息长度小于2的64幂,是因为长度信息的位数为64位。
信息分组处理
对输入信息进行填充后,长度为512的倍数,然后按照512的长度进行分组,可以得到一定数量的明文分组,这里用A、B、C 、 D等明文分组。对于每一个明文分组,都要重复反复的处理,这些与MD5都是相同的。
而对于每个512位的明文分组,SHA1将其再分成16份更小的明文分组,称为子明文分组,每个子明文分组为32位,我们且使用M[t](t= 0, 1,……15)来表示这16个子明文分组。然后需要将这16个子明文分组扩充到80个子明文分组,我们将其记为W[t](t= 0, 1,……79),扩充的具体方法是:当0≤t≤15时,Wt = Mt;当16≤t≤79时,Wt = ( Wt-3 ⊕ Wt-8⊕ Wt-14⊕ Wt-16) <<< 1,从而得到80个子明文分组。
初始化缓存
所谓初始化缓存就是为链接变量赋初值。前面我们实现MD5算法时,说过由于摘要是128位,以32位为计算单位,所以需要4个链接变量。同样SHA-1采用160位的信息摘要,也以32位为计算长度,就需要5个链接变量。我们记为A、B、C、D、E。其初始赋值分别为:A = 0x67452301、B = 0xEFCDAB89、C = 0x98BADCFE、D = 0x10325476、E = 0xC3D2E1F0。
如果我们对比前面说过的MD5算法就会发现,前4个链接变量的初始值是一样的,因为它们本来就是同源的。
计算信息摘要
A)、将A左移5为与 函数的结果求和,再与对应的子明文分组、E以及计算常数求和后的结果赋予H0。
(B)、将A的值赋予H1。
(C)、将B左移30位,并赋予H2。
(D)、将C的值赋予H3。
(E)、将D的值赋予H4。
(F)、最后将H0、H1、H2、H3、H4的值分别赋予A、B、C、D
这个过程表示如下:
1 | public static void sha1Encrypt(String str) throws NoSuchAlgorithmException { |
参考内容: