一、MD5算法
MD5消息摘要算法(Message Digest Algorithm)是R.Rivest设计的,它对输入的任意长度的消息进行运算,产生一个128位的消息摘要。随着穷举攻击和密码分析的发展,MD5算法已经不再那么流行了。
1、算法原理
1)数据填充
填充消息使其与448模512同余(长度 ≡ 448 mod 521),即填充后的消息长度是比512的倍数仅小64位的数。即使消息长度本身已经符号上述长度,仍然需要填充(填充方法是附一个1在消息后面,然后用0来进行填充,直到消息的长度与448模512同余)。至少填充1位,至多填充512位。
2)添加长度
在数据填充的结果之后附上64位的消息长度。如果填充前消息的长度大于2^64,则只使用其低64位。添加完填充位和消息长度之后,最终的消息长度是512的整数倍。
3)初始化变量
初始化4个变量(A=0x67452301,B=0xEFCDAB89,C=0x98BADCFE,D=0x10325476,分别都是一个32位的寄存器)来计算消息摘要,并且以小端形式来存放,即如下:
01 23 45 67 89 AB CD EF FE DC BA 98 76 54 32 10
4)数据处理
4个辅助函数:
F(X,Y,Z) = (X&Y)|((~X)&Z)
G(X,Y,Z) = (X&Z)|(Y&(~Z))
H(X,Y,Z) = X ^ Y ^ Z
I(XY,Z) = Y ^ (X|(~Z))
把消息分以512位为一分组进行处理,每一个分组进行4轮变换,以上面所说4个常数为起始变量进行计算,重新输出4个变量,以这4个变量再进行下一分组的运算,如果已经是最后一个分组,则这4个变量为最后的结果,即MD5值。
具体代码实现可参考MD5算法和MD5加密算法原理及实现。
二、SHA1算法和DES算法
SHA1算法参考SHA1算法实现及详解
DES算法参考DES算法原理完整版
三、MIME/BASE64算法
MIME是多部分、多媒体电子邮件、WWW超文本的一种编码标准,用于传送图形、声音和传真等非文本数据。MIME定义于RFC1341,用MIMEENCODE方法将二进制数据转换为一种被称为BASE64的ASCII子集的字符的组合。MIME/BASE64将字符流存放入一个24位的缓冲区,缺字符的地方补零,然后将缓冲区截断为4个部分,高位在先,每个部分6位,用下面的64个字符重新表示:“ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/”。如果输入只有一个或两个字节,那么输出将用“=”补足,这样可以隔断附加信息造成编码的混乱。
四、PHP内置加密函数
1、单向字符串散列
string crypt ( string str [, string salt ] )
返回一个基于标准 UNIX DES 算法或系统上其他可用的替代算法的散列字符串。
str是需要加密的字符串,salt是加密时使用的干扰串。如果省略salt,则会随机生成一个干扰串。
在 crypt() 函数支持多重散列的系统上,下面的常量根据相应的类型是否可用被设置为 0 或 1:
CRYPT_STD_DES - 基于标准 DES 算法的散列使用 “./0-9A-Za-z” 字符中的两个字符作为盐值。在盐值中使用非法的字符将导致 crypt() 失败。
CRYPT_EXT_DES - 扩展的基于 DES 算法的散列。其盐值为 9 个字符的字符串,由 1 个下划线后面跟着 4 字节循环次数和 4 字节盐值组成。它们被编码成可打印字符,每个字符 6 位,有效位最少的优先。0 到 63 被编码为 “./0-9A-Za-z”。在盐值中使用非法的字符将导致 crypt() 失败。
CRYPT_MD5 - MD5 散列使用一个以
1
1
1 开始的 12 字符的字符串盐值。
CRYPT_BLOWFISH - Blowfish 算法使用如下盐值:“
2
a
2a
2a”,一个两位 cost 参数,“$” 以及 64 位由 “./0-9A-Za-z” 中的字符组合而成的字符串。在盐值中使用此范围之外的字符将导致 crypt() 返回一个空字符串。两位 cost 参数是循环次数以 2 为底的对数,它的范围是 04-31,超出这个范围将导致 crypt() 失败。 PHP 5.3.7 之前只支持 “
2
a
2a
2a” 作为盐值的前缀,PHP 5.3.7 开始引入了新的前缀来修正一个在Blowfish实现上的安全风险。可以参考» this document来了解关于这个修复的更多信息。总而言之,开发者如果仅针对 PHP 5.3.7及之后版本进行开发,那应该使用 “
2
y
2y
2y” 而非 “
2
a
2a
2a”
CRYPT_SHA256 - SHA-256 算法使用一个以
5
5
5 开头的 16 字符字符串盐值进行散列。如果盐值字符串以 “rounds=$” 开头,N 的数字值将被用来指定散列循环的执行次数,这点很像 Blowfish 算法的 cost 参数。默认的循环次数是 5000,最小是 1000,最大是 999,999,999。超出这个范围的 N 将会被转换为最接近的值。
CRYPT_SHA512 - SHA-512 算法使用一个以
6
6
6 开头的 16 字符字符串盐值进行散列。如果盐值字符串以 “rounds=$” 开头,N 的数字值将被用来指定散列循环的执行次数,这点很像 Blowfish 算法的 cost 参数。默认的循环次数是 5000,最小是 1000,最大是 999,999,999。超出这个范围的 N 将会被转换为最接近的值。
PHP 设置了一个名为 CRYPT_SALT_LENGTH 的常量,用来表示可用散列允许的最长可用盐值。
2、计算字符串的 MD5 散列值
string md5 ( string str [, bool raw_output = FALSE ] )
以 32 字符十六进制数字形式返回散列值。
参数str是原始字符串。
如果可选的 raw_output 被设置为 TRUE,那么 MD5 报文摘要将以16字节长度的原始二进制格式返回。
3、计算字符串的 sha1 散列值
string sha1 ( string str [, bool raw_output = false ] )
参数str是输入字符串。
如果可选的 raw_output 参数被设置为 TRUE, 那么 sha1 摘要将以 20 字符长度的原始格式返回, 否则返回值是一个 40 字符长度的十六进制数字。
4、使用 MIME base64 对数据进行编码
string base64_encode ( string data )
成功返回编码后的字符串数据, 失败时返回 FALSE。
设计此种编码是为了使二进制数据可以通过非纯 8-bit 的传输层传输,例如电子邮件的主体。Base64-encoded 数据要比原始数据多占用 33% 左右的空间。
5、对使用 MIME base64 编码的数据进行解码
string base64_decode ( string data [, bool strict = false ] )
返回原始数据, 或者在失败时返回 FALSE。返回的数据可能是二进制的。
参数data是编码过的数据。
参数strict是可选的,当设置 strict 为 TRUE 时,一旦输入的数据超出了 base64 字母表,将返回 FALSE。 否则会静默丢弃无效的字符。
五、加密扩展库Mcrypt和Mhash
Mcrypt扩展库可以实现加密解密功能;Mhash扩展库包含了多种hash算法实现的混编函数。
Mcrypt的具体用法参见PHP手册Mcrypt
Mhash的具体用法参见PHP手册Mhash