频 道 直 达 - 新闻 - 培训 - 软件 - 教程 - 前沿 - 组网 - 系统应用 - 安全 - 编程 - 存储 - 操作系统 - 数据库 - 服务器 - 专题 - 产品 - 案例库 - 读书 - 博客 - BBS
51CTO.COM_中国最大的网络技术网站
找资料:

31.1 实现md5加密

作者: 王润森、王俊杰 出处:人民邮电出版社  2007-10-15 17:11    砖    好    评论   进入论坛
阅读提示:《精通JavaScript动态网页编程》第三十一章主要讲的是加密算法,本节介绍了如何实现md5加密。

第31章  加密算法

加密解密是程序设计中不可缺少的重要内容。网页设计中经常使用的加密算法有md5、base64等。而md5加密,由于迄今为止仍是不可破解的(理论上并非如此,仅就破解的实际可能却是如此),因此,至今仍广泛应用于保存用户密码,本章介绍这种算法的JavaScript实现。此外,编写自己的加密算法,也不失为一种有效的保密手段,但是,要实现比较复杂的加密技术是非常困难的,本章只给出一种最简单的字符替换的加密算法,提供一种思路,以供读者参考。

31.1  实现md5加密

md5加密是目前国内网页设计中使用最多的口令加密方式,本节给出一段示例代码,可以实现输入内容的md5加密。

技术要点

本节代码主要使用了位运算和位移运算,其主要用法和相关内容如下。

在JavaScript中,位运算符分为两种,一种是普通位运算符,一种是位移运算符。在进行运算前,都先将操作数转换为32位的二进制整数,然后再进行相应的运算,最后的输出结果以十进制整数表示。

普通位运算符有4种:位与“&”运算符、位或“|”运算符、位异或“^”运算符和位非“~”运算符。

位非操作也是先将操作数转换为32位二进制数字,然后对每一位进行取反操作(0替换为1,1替换为0),所得结果为二进制数的补码表示法。

位运算符还可对其他数值进行位运算。例如,对十六进制数0xFF(十进制的255)进行位非操作(~0xFF)后的结果为十进制的?256。

位移运算符有两个操作数,第1个操作数是被操作数,第2个操作数是被操作数要被按位移动的位数。

位移运算符有3种:左移位(空出的位补0)运算符“<<”、右移位(空出的位补符号位)运算符“>>”、右移位(空出的位补0)运算符“>>>”。例如,表达式“4<<3”的含义为“00000100左移3位”,结果为00100000,十进制表示为32;表达式“?9>>2”的含义为“11110111右移2位”,结果为11111101,十进制表示为-3;表达式“32>>>3”的含义为“00100000右移3位”,结果为00000100,十进制表示为4。

实现代码

 <!------------------------------文件名:31.1.htm------------------------------>
<html>
<head>   
<meta http-equiv="Content-Type" content="text/html;charset=gb2312">
<title>实现md5加密</title>
</head>
<body bgcolor="#ffc0c0">
<h1>实现md5加密</h1><hr>
<input id="test" value="cool">
<input type="button" value="加密" onclick="alert('加密的结果是:'+HexMd5(test.value))">
<br><br>字符串“abc”加密后的结果是:
<br><br>900150983cd24fb0d963f7d28e17f72
<script language="JavaScript">
<!--
//大小写标志等基本变量声明
var hexcase=0;
var b64pad="";
var chrsz=8;

//调用的主函数
function HexMd5(s)
{
return binl2hex(CoreMd5(str2binl(s),s.length*chrsz));
}
function b64_md5(s)
{
return binl2b64(CoreMd5(str2binl(s),s.length*chrsz));
}
function hex_hmac_md5(key,data)
{
return binl2hex(core_hmac_md5(key,data));
}
function b64_hmac_md5(key,data)
{
return binl2b64(core_hmac_md5(key,data));
}

//和以后的相容,和HexMd5(s)差不多
function calcMD5(s)
{
return binl2hex(CoreMd5(str2binl(s),s.length*chrsz));
}

//一个最简单的加密,可以做测试
function md5_vm_test()
{
return HexMd5("abc")=="900150983cd24fb0d963f7d28e17f72";
}

//加密一定长度的字符串
function CoreMd5(x,len)
{
//填补空缺
x[len>>5]|=0x80<<((len)%32);
x[(((len+64)>>>9)<<4)+14]=len;

//加密算法开始
var a=1732584193;
var b=-271733879;
var c=-1732584194;
var d=271733878;
              for(var i=0;i<x.length;i+=16)
{
var olda=a;
var oldb=b;
var oldc=c;
var oldd=d;


//第1次加密
a=OfMd5(a,b,c,d,x[i+0],7,-680876936);
d=OfMd5(d,a,b,c,x[i+1],12,-389564586);
c=OfMd5(c,d,a,b,x[i+2],17,606105819);
b=OfMd5(b,c,d,a,x[i+3],22,-1044525330);

a=OfMd5(a,b,c,d,x[i+4],7,-176418897);
d=OfMd5(d,a,b,c,x[i+5],12,1200080426);
c=OfMd5(c,d,a,b,x[i+6],17,-1473231341);
b=OfMd5(b,c,d,a,x[i+7],22,-45705983);

a=OfMd5(a,b,c,d,x[i+8],7,1770035416);
d=OfMd5(d,a,b,c,x[i+9],12,-1958414417);
c=OfMd5(c,d,a,b,x[i+10],17,-42063);
b=OfMd5(b,c,d,a,x[i+11],22,-1990404162);

a=OfMd5(a,b,c,d,x[i+12],7,1804603682);
d=OfMd5(d,a,b,c,x[i+13],12,-40341101);
c=OfMd5(c,d,a,b,x[i+14],17,-1502002290);
b=OfMd5(b,c,d,a,x[i+15],22,1236535329);


//第2次加密
a=md5_gg(a,b,c,d,x[i+1],5,-165796510);
d=md5_gg(d,a,b,c,x[i+6],9,-1069501632);
c=md5_gg(c,d,a,b,x[i+11],14,643717713);
b=md5_gg(b,c,d,a,x[i+0],20,-373897302);

a=md5_gg(a,b,c,d,x[i+5],5,-701558691);
d=md5_gg(d,a,b,c,x[i+10],9,38016083);
c=md5_gg(c,d,a,b,x[i+15],14,-660478335);
b=md5_gg(b,c,d,a,x[i+4],20,-405537848);

a=md5_gg(a,b,c,d,x[i+9],5,568446438);
d=md5_gg(d,a,b,c,x[i+14],9,-1019803690);
c=md5_gg(c,d,a,b,x[i+3],14,-187363961);
b=md5_gg(b,c,d,a,x[i+8],20,1163531501);

a=md5_gg(a,b,c,d,x[i+13],5,-1444681467);
d=md5_gg(d,a,b,c,x[i+2],9,-51403784);
c=md5_gg(c,d,a,b,x[i+7],14,1735328473);
b=md5_gg(b,c,d,a,x[i+12],20,-1926607734);


//第3次加密
a=md5_hh(a,b,c,d,x[i+5],4,-378558);
d=md5_hh(d,a,b,c,x[i+8],11,-2022574463);
c=md5_hh(c,d,a,b,x[i+11],16,1839030562);
b=md5_hh(b,c,d,a,x[i+14],23,-35309556);

a=md5_hh(a,b,c,d,x[i+1],4,-1530992060);
d=md5_hh(d,a,b,c,x[i+4],11,1272893353);
c=md5_hh(c,d,a,b,x[i+7],16,-155497632);
b=md5_hh(b,c,d,a,x[i+10],23,-1094730640);

a=md5_hh(a,b,c,d,x[i+13],4,681279174);
d=md5_hh(d,a,b,c,x[i+0],11,-358537222);
c=md5_hh(c,d,a,b,x[i+3],16,-722521979);
b=md5_hh(b,c,d,a,x[i+6],23,76029189);

a=md5_hh(a,b,c,d,x[i+9],4,-640364487);
d=md5_hh(d,a,b,c,x[i+12],11,-421815835);
c=md5_hh(c,d,a,b,x[i+15],16,530742520);
b=md5_hh(b,c,d,a,x[i+2],23,-995338651);


//第4次加密
a=md5_ii(a,b,c,d,x[i+0],6,-198630844);
d=md5_ii(d,a,b,c,x[i+7],10,1126891415);
c=md5_ii(c,d,a,b,x[i+14],15,-1416354905);
b=md5_ii(b,c,d,a,x[i+5],21,-57434055);

a=md5_ii(a,b,c,d,x[i+12],6,1700485571);
d=md5_ii(d,a,b,c,x[i+3],10,-1894986606);
c=md5_ii(c,d,a,b,x[i+10],15,-1051523);
b=md5_ii(b,c,d,a,x[i+1],21,-2054922799);

a=md5_ii(a,b,c,d,x[i+8],6,1873313359);
d=md5_ii(d,a,b,c,x[i+15],10,-30611744);
c=md5_ii(c,d,a,b,x[i+6],15,-1560198380);
b=md5_ii(b,c,d,a,x[i+13],21,1309151649);

a=md5_ii(a,b,c,d,x[i+4],6,-145523070);
d=md5_ii(d,a,b,c,x[i+11],10,-1120210379);
c=md5_ii(c,d,a,b,x[i+2],15,718787259);
b=md5_ii(b,c,d,a,x[i+9],21,-343485551);
                    //第5次加密
a=safe_add(a,olda);
b=safe_add(b,oldb);
c=safe_add(c,oldc);
d=safe_add(d,oldd);
}
//返回结果
return Array(a,b,c,d);
}

//下面的函数都是用于实现加密的
function md5_cmn(q,a,b,x,s,t)
{
return safe_add(bit_rol(safe_add(safe_add(a,q),safe_add(x,t)),s),b);
}
function OfMd5(a,b,c,d,x,s,t)
{
return md5_cmn((b&c)|((~b)&d),a,b,x,s,t);
}
function md5_gg(a,b,c,d,x,s,t)
{
return md5_cmn((b&d)|(c&(~d)),a,b,x,s,t);
}
function md5_hh(a,b,c,d,x,s,t)
{
return md5_cmn(b^c^d,a,b,x,s,t);
}
function md5_ii(a,b,c,d,x,s,t)
{
return md5_cmn(c^(b|(~d)),a,b,x,s,t);
}

//计算一些md5算法中的关键值
function core_hmac_md5(key,data)
{
var bkey=str2binl(key);
if(bkey.length>16)
bkey=CoreMd5(bkey,key.length*chrsz);
var ipad=Array(16),opad=Array(16);
for(var i=0;i<16;i++)
{
ipad[i]=bkey[i]^0x36363636;
opad[i]=bkey[i]^0x5c5c5c5c;
}
var hash=CoreMd5(ipad.concat(str2binl(data)),512+data.length*chrsz);
return CoreMd5(opad.concat(hash),512+128);
}
//加密算法函数
function safe_add(x,y)
{
var lsw=(x&0xFFFF)+(y&0xFFFF);
var msw=(x>>16)+(y>>16)+(lsw>>16);
return (msw<<16)|(lsw&0xFFFF);
}
function bit_rol(num,cnt)
{
return (num<<cnt)|(num>>>(32-cnt));
}
//对ASCII码的处理
function str2binl(str)
{
var bin=Array();
var mask=(1<<chrsz)-1;
for(var i=0;i<str.length*chrsz;i+=chrsz)
{
bin[i>>5]|=(str.charCodeAt(i/chrsz)&mask)<<(i%32);
}
return bin;
}
//少量字符的处理
function binl2hex(binarray)
{
var hex_tab=hexcase?"0123456789ABCDEF":"0123456789abcdef";
var str="";
for(var i=0;i<binarray.length*4;i++)
{
str+=hex_tab.charAt((binarray[i>>2]>>((i%4)*8+4))&0xF)
+hex_tab.charAt((binarray[i>>2]>>((i%4)*8))&0xF);
}
return str;
}

//处理64位的字符串
function binl2b64(binarray)
{
var tab="ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz0123456789+/";
var str="";
for(var i=0;i<binarray.length*4;i+=3)
{
var triplet=(((binarray[i>>2]>>8*(i%4))&0xFF)<<16)|
(((binarray[i+1>>2]>>8*((i+1)%4))&0xFF)<<8)|
((binarray[i+2>>2]>>8*((i+2)%4))&0xFF);
for(var j=0;j<4;j++)
{
if(i*8+j*6>binarray.length*32)
{
str+=b64pad;
}
else
{
str+=tab.charAt((triplet>>6*(3-j))&0x3F);
}
}
}
return str;
}
//-->
</script>
</body>
</html>

运行该程序后,出现如图31.1所示的显示界面。在文本框中输入abc,单击“加密”按钮,弹出一个对话框,显示加密结果,可以看到,与页面显示结果相同,如图31.2所示。读者也可以输入其他字符串进行加密,并与其他程序计算的加密结果进行比较,看是否相同。

    图31.1  代码31.1.htm显示结果  
图31.2  加密结果

源程序解读
(1)程序建立了一个名为test、值为cool的文本框和一个“加密”按钮。文本框用于输入要加密的内容,“加密按钮”的onclick事件弹出一个对话框,调用函数HexMd5(test.value)对输入的内容进行加密,并显示加密结果。由于涉及md5加密的具体算法,此处不再详细说明,只介绍程序中函数的调用关系。

(2)函数HexMd5(test.value) 的结构很简单,只是调用了binl2hex( )函数,并将CoreMd5( )函数的结果作为其参数使用。

(3)在函数binl2b64(binarray) 中,则对可能出现的字符串进行列举,并加以处理。

(4)函数md5_vm_test( )是一个测试函数,对字符串“abc”进行加密,并与已知的md5加密结果进行比较,若相同,则返回true,表示算法正确;否则,返回false,表示算法有误。

【责任编辑:杜书 TEL:(010)68476606】

回书目   上一节   下一节
专题
汶川大地震 IT技术人在行动
解析35岁技术人的价值与出路
LAMP技术精解
调查:十大发现 解秘技术人
北漂技术人90天求职纪实
我也说两句

匿名发表

(如果看不清请点击图片进行更换)


中 国 最 大 的 网 络 技 术 网 站 ·
技 术 成 就 梦 想
订阅技术快讯
电子杂志下载
名称:SQL Server数据库管理精品黄皮书
简介:书中文章经过精挑细选,便于用户能根据自己的实际工作和学习,快速在本书寻找到相关资料。内容涵盖了SQL Server的安装与升级、语句查询、数据备份和恢复、自动化任务、数据同步、数据字典、安全和预防、性能和优化、集群等各方面应用信息,以及DBA管理人员在数据库管理工作中
名称:2007路由技术大全
简介:《2007路由技术大全》由51CTO.com网站特别策划制作,该书包括路由器技术、路由器产品、路由器配置、安全设置、路由器故障处理、路由器密码恢复,以及广大网友在实践使用中的心得经验和技巧文章,内容注重实用性,适用于初学者入门,也适合多年从业者提高,是一本实践和理论完
名称:网络安全精品应用黄皮书
简介:《2007精品网络安全黄皮书》包括了9个大类24个小类, 800余篇文章,内容包含了熊猫烧香病毒、DDOS攻击、ARP病等热点问题的介绍及解决方案。从病毒查杀、防范、系统、数据等各方面的安全设置到黑客技术的了解、防范,涉及到了安全应用的全部领域, 由浅至深内容全面。
浏览器的战国时代
浏览器的战国时代
ARP攻击防范与解决方案
ARP攻击防范与解决方案
NAC安全访问控制
NAC安全访问控制
· NAC安全访问控制
· 网络布线测试仪器
· Windows Server 2008专..
· Windows远程桌面应用
· 网络故障排除宝典
· 运营商封堵ADSL共享 中..
· 解析35岁技术人的价值..
· 世纪枭雄比尔盖茨的王..
· 主流品牌防火墙配置
· ASP.NET开发教程
· 超级计算机TOP500专题
· Vista SP1对决XP SP3
· SQL Server 2008/2005..
· 程序员如何成长?
· C#技术开发指南
· 虚拟化技术还有点“虚”
ARP攻击防范与解决方案
ARP攻击防范与解决方案
SQL Server 2008/2005全解
SQL Server 2008/2005全解
SOA 面向服务架构
SOA 面向服务架构
· SOA 面向服务架构
· SQL Server 2008/2005..
· Apache技术专题
· 三层交换技术专题
· SQL Server入门到精通
· Windows远程桌面应用
· C#技术开发指南
· Apache技术专题
· Windows集群服务应用
· C#技术开发指南
· 国际文档格式标准开战
· 路由器设置与口令恢复
· Linux 集群技术专题
· PHP开发应用手册
· SOA 面向服务架构
· 企业数据恢复指南
ARP攻击防范与解决方案
ARP攻击防范与解决方案
SQL Server 2008/2005全解
SQL Server 2008/2005全解
SQL Server入门到精通
SQL Server入门到精通
· SQL Server入门到精通
· SQL Server 2008/2005..
· SOA 面向服务架构
· Apache技术专题
· C#技术开发指南
· 三层交换技术专题
· Apache技术专题
· C#技术开发指南
· Windows远程桌面应用
· 企业数据恢复指南
· Windows集群服务应用
· 路由器设置与口令恢复
· Linux 集群技术专题
· SOA 面向服务架构
· 了解统一威胁管理(UTM)..
· 反垃圾邮件技术应用