使用JAVA实现以上设计,先实现摘要,主要通过调用JDK API进行封装,使用程序可以方便调用

ISecurity接口类:

 1 package com.xqrj.security;
2
3 public interface ISecurity {
4 /**
5 * 设置算法
6 * @param algorithm 算法规则
7 * @return void
8 */
9 public void setAlgorithm(String algorithm);
10 /**
11 * 设置密钥
12 * @param key 加密密钥
13 * @return void
14 */
15 public void setKey(byte[] key);
16 /**
17 * 设置密文编码
18 * @param encodeMode 1:BASE64 2:HEX (默认为1)
19 * @return
20 */
21 public void setEncodeMode(int encodeMode);
22 /**
23 * 其它设置
24 * @param otherData 加密的其它设置
25 * @return void
26 */
27 public void setOther(byte[] otherData);
28 /**
29 * 构建加密数据
30 * @param buff 需要加密的数据
31 * @return String 加密后的数据(经过编码)
32 */
33 public byte[] buildData(byte[] buff) throws SecurityException;
34 }

IDigest接口类,继承安全接口:

1 package com.xqrj.security.digest;
2
3 import com.xqrj.security.ISecurity;
4
5 public interface IDigest extends ISecurity {
6
7 }

DigestDigestImpl摘要抽象类:主要实现功能都在此类中实现

 1 package com.xqrj.security.digest;
2
3 import java.security.MessageDigest;
4 import java.security.NoSuchAlgorithmException;
5
6 import com.xqrj.security.encrypt.IEncrypt;
7 import com.xqrj.util.PublicUtil;
8
9 public abstract class DigestDigestImpl implements IDigest {
10 private String algorithm = "MD5";
11 private int encodeMode = 1;
12 private byte[] key;
13 private byte[] otherData;
14
15 public void setAlgorithm(String algorithm) {
16 this.algorithm = algorithm;
17 }
18 public void setEncodeMode(int encodeMode) {
19 this.encodeMode = encodeMode;
20 }
21 public void setKey(byte[] key) {
22 this.key = key;
23 }
24 public void setOther(byte[] otherData) {}
25
26 public byte[] buildData(byte[] buff) throws SecurityException {
27 MessageDigest msgDigest = null;
28 try {
29 msgDigest = MessageDigest.getInstance(algorithm);
30 } catch (NoSuchAlgorithmException e) {
31 throw new SecurityException(e.getMessage());
32 }
33 msgDigest.update(buff);
34 byte[] data = msgDigest.digest();
35 switch(encodeMode) {
36 case 1: //BASE64
37 return PublicUtil.getBase64Encode(data).getBytes();
38 case 2: //HEX
39 return new String(PublicUtil.bytesToHex(data)).getBytes();
40 default: //BASE64
41 return PublicUtil.getBase64Encode(data).getBytes();
42 }
43 }
44 }

DigestDigest类:无具体代码,只是提供用于调用

1 package com.xqrj.security.digest;
2
3 public class DigestDigest extends DigestDigestImpl {
4
5 }

SecurityTest测试类:

package com.xqrj.security;

import java.security.Security;

import com.xqrj.security.decrypt.DesDecrypt;
import com.xqrj.security.digest.DigestDigest;
import com.xqrj.security.encrypt.DesEncrypt;

public class SecurityTest {
public static void main(String[] args) {
//需要加密的数据
byte[] buff = "abcdefgh12345678中文".getBytes();
//密钥KEY
String key = "";
//使用何种算法
String algorithm = "";
//其它数据
String other = "";
//数据编码(1:BASE64 2:HEX)
int encodeMode = 1;
//结果数据
byte[] resBuff = null;
try {
//*********************************************************************************
//摘要测试
DigestDigest digestEncrypt = new DigestDigest();
//MD2、MD5用HEX进行编码
digestEncrypt.setAlgorithm("MD2");
digestEncrypt.setEncodeMode(2);
resBuff = digestEncrypt.buildData(buff);
System.out.println("生成的MD2摘要数据:"+new String(resBuff));
digestEncrypt.setAlgorithm("MD5");
resBuff = digestEncrypt.buildData(buff);
System.out.println("生成的MD5摘要数据:"+new String(resBuff));
//SHA用BASE进行编码
digestEncrypt.setAlgorithm("SHA");
digestEncrypt.setEncodeMode(1);
resBuff = digestEncrypt.buildData(buff);
System.out.println("生成的SHA-1摘要数据:"+new String(resBuff));
digestEncrypt.setAlgorithm("SHA-256");
resBuff = digestEncrypt.buildData(buff);
System.out.println("生成的SHA-256摘要数据:"+new String(resBuff));
digestEncrypt.setAlgorithm("SHA-384");
resBuff = digestEncrypt.buildData(buff);
System.out.println("生成的SHA-384摘要数据:"+new String(resBuff));
digestEncrypt.setAlgorithm("SHA-512");
resBuff = digestEncrypt.buildData(buff);
System.out.println("生成的SHA-512摘要数据:"+new String(resBuff));
//*********************************************************************************
} catch(Exception e) {
e.printStackTrace();
}
}
}

摘要功能完成,MD5我们主要用于对用户登录密码进行加密,然后到后台验证(数据库中只保存MD5生成的数据),这就涉及到客户端用户输入密码后,需要对用户输入的密码进行先加密然后在提交到后台进行验证。

为什么不将用户输入的密码提交到后台,由后台进行加密后在验证,有很多人都应该知道这里面的原因,但我还是解释一下,用户输入的密码在网络中传递是不安全的,所以在本地加密,然后将密文提交到后台进行验证。

以下为MD5,js代码,此代码不是我写的,是在网上找到,文章找不到了所以也不能提供链接了,如下:

  1 /*
2 * 返回MD5加密后字符串
3 */
4 function MD5(sMessage) {
5 function RotateLeft(lValue, iShiftBits) { return (lValue<<iShiftBits) | (lValue>>>(32-iShiftBits)); }
6 function AddUnsigned(lX,lY) {
7 var lX4,lY4,lX8,lY8,lResult;
8 lX8 = (lX & 0x80000000);
9 lY8 = (lY & 0x80000000);
10 lX4 = (lX & 0x40000000);
11 lY4 = (lY & 0x40000000);
12 lResult = (lX & 0x3FFFFFFF)+(lY & 0x3FFFFFFF);
13 if (lX4 & lY4) return (lResult ^ 0x80000000 ^ lX8 ^ lY8);
14 if (lX4 | lY4) {
15 if (lResult & 0x40000000) return (lResult ^ 0xC0000000 ^ lX8 ^ lY8);
16 else return (lResult ^ 0x40000000 ^ lX8 ^ lY8);
17 } else return (lResult ^ lX8 ^ lY8);
18 }
19 function F(x,y,z) { return (x & y) | ((~x) & z); }
20 function G(x,y,z) { return (x & z) | (y & (~z)); }
21 function H(x,y,z) { return (x ^ y ^ z); }
22 function I(x,y,z) { return (y ^ (x | (~z))); }
23 function FF(a,b,c,d,x,s,ac) {
24 a = AddUnsigned(a, AddUnsigned(AddUnsigned(F(b, c, d), x), ac));
25 return AddUnsigned(RotateLeft(a, s), b);
26 }
27 function GG(a,b,c,d,x,s,ac) {
28 a = AddUnsigned(a, AddUnsigned(AddUnsigned(G(b, c, d), x), ac));
29 return AddUnsigned(RotateLeft(a, s), b);
30 }
31 function HH(a,b,c,d,x,s,ac) {
32 a = AddUnsigned(a, AddUnsigned(AddUnsigned(H(b, c, d), x), ac));
33 return AddUnsigned(RotateLeft(a, s), b);
34 }
35 function II(a,b,c,d,x,s,ac) {
36 a = AddUnsigned(a, AddUnsigned(AddUnsigned(I(b, c, d), x), ac));
37 return AddUnsigned(RotateLeft(a, s), b);
38 }
39 function ConvertToWordArray(sMessage) {
40 var lWordCount;
41 var lMessageLength = sMessage.length;
42 var lNumberOfWords_temp1=lMessageLength + 8;
43 var lNumberOfWords_temp2=(lNumberOfWords_temp1-(lNumberOfWords_temp1 % 64))/64;
44 var lNumberOfWords = (lNumberOfWords_temp2+1)*16;
45 var lWordArray=Array(lNumberOfWords-1);
46 var lBytePosition = 0;
47 var lByteCount = 0;
48 while ( lByteCount < lMessageLength ) {
49 lWordCount = (lByteCount-(lByteCount % 4))/4;
50 lBytePosition = (lByteCount % 4)*8;
51 lWordArray[lWordCount] = (lWordArray[lWordCount] | (sMessage.charCodeAt(lByteCount)<<lBytePosition));
52 lByteCount++;
53 }
54 lWordCount = (lByteCount-(lByteCount % 4))/4;
55 lBytePosition = (lByteCount % 4)*8;
56 lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80<<lBytePosition);
57 lWordArray[lNumberOfWords-2] = lMessageLength<<3;
58 lWordArray[lNumberOfWords-1] = lMessageLength>>>29;
59 return lWordArray;
60 }
61 function WordToHex(lValue) {
62 var WordToHexValue="",WordToHexValue_temp="",lByte,lCount;
63 for (lCount = 0;lCount<=3;lCount++) {
64 lByte = (lValue>>>(lCount*8)) & 255;
65 WordToHexValue_temp = "0" + lByte.toString(16);
66 WordToHexValue = WordToHexValue + WordToHexValue_temp.substr(WordToHexValue_temp.length-2,2);
67 }
68 return WordToHexValue;
69 }
70 var x=Array();
71 var k,AA,BB,CC,DD,a,b,c,d
72 var S11=7, S12=12, S13=17, S14=22;
73 var S21=5, S22=9 , S23=14, S24=20;
74 var S31=4, S32=11, S33=16, S34=23;
75 var S41=6, S42=10, S43=15, S44=21;
76 // Steps 1 and 2. Append padding bits and length and convert to words
77 x = ConvertToWordArray(sMessage);
78 // Step 3. Initialise
79 a = 0x67452301; b = 0xEFCDAB89; c = 0x98BADCFE; d = 0x10325476;
80 // Step 4. Process the message in 16-word blocks
81 for (k=0;k<x.length;k+=16) {
82 AA=a; BB=b; CC=c; DD=d;
83 a=FF(a,b,c,d,x[k+0], S11,0xD76AA478);
84 d=FF(d,a,b,c,x[k+1], S12,0xE8C7B756);
85 c=FF(c,d,a,b,x[k+2], S13,0x242070DB);
86 b=FF(b,c,d,a,x[k+3], S14,0xC1BDCEEE);
87 a=FF(a,b,c,d,x[k+4], S11,0xF57C0FAF);
88 d=FF(d,a,b,c,x[k+5], S12,0x4787C62A);
89 c=FF(c,d,a,b,x[k+6], S13,0xA8304613);
90 b=FF(b,c,d,a,x[k+7], S14,0xFD469501);
91 a=FF(a,b,c,d,x[k+8], S11,0x698098D8);
92 d=FF(d,a,b,c,x[k+9], S12,0x8B44F7AF);
93 c=FF(c,d,a,b,x[k+10],S13,0xFFFF5BB1);
94 b=FF(b,c,d,a,x[k+11],S14,0x895CD7BE);
95 a=FF(a,b,c,d,x[k+12],S11,0x6B901122);
96 d=FF(d,a,b,c,x[k+13],S12,0xFD987193);
97 c=FF(c,d,a,b,x[k+14],S13,0xA679438E);
98 b=FF(b,c,d,a,x[k+15],S14,0x49B40821);
99 a=GG(a,b,c,d,x[k+1], S21,0xF61E2562);
100 d=GG(d,a,b,c,x[k+6], S22,0xC040B340);
101 c=GG(c,d,a,b,x[k+11],S23,0x265E5A51);
102 b=GG(b,c,d,a,x[k+0], S24,0xE9B6C7AA);
103 a=GG(a,b,c,d,x[k+5], S21,0xD62F105D);
104 d=GG(d,a,b,c,x[k+10],S22,0x2441453);
105 c=GG(c,d,a,b,x[k+15],S23,0xD8A1E681);
106 b=GG(b,c,d,a,x[k+4], S24,0xE7D3FBC8);
107 a=GG(a,b,c,d,x[k+9], S21,0x21E1CDE6);
108 d=GG(d,a,b,c,x[k+14],S22,0xC33707D6);
109 c=GG(c,d,a,b,x[k+3], S23,0xF4D50D87);
110 b=GG(b,c,d,a,x[k+8], S24,0x455A14ED);
111 a=GG(a,b,c,d,x[k+13],S21,0xA9E3E905);
112 d=GG(d,a,b,c,x[k+2], S22,0xFCEFA3F8);
113 c=GG(c,d,a,b,x[k+7], S23,0x676F02D9);
114 b=GG(b,c,d,a,x[k+12],S24,0x8D2A4C8A);
115 a=HH(a,b,c,d,x[k+5], S31,0xFFFA3942);
116 d=HH(d,a,b,c,x[k+8], S32,0x8771F681);
117 c=HH(c,d,a,b,x[k+11],S33,0x6D9D6122);
118 b=HH(b,c,d,a,x[k+14],S34,0xFDE5380C);
119 a=HH(a,b,c,d,x[k+1], S31,0xA4BEEA44);
120 d=HH(d,a,b,c,x[k+4], S32,0x4BDECFA9);
121 c=HH(c,d,a,b,x[k+7], S33,0xF6BB4B60);
122 b=HH(b,c,d,a,x[k+10],S34,0xBEBFBC70);
123 a=HH(a,b,c,d,x[k+13],S31,0x289B7EC6);
124 d=HH(d,a,b,c,x[k+0], S32,0xEAA127FA);
125 c=HH(c,d,a,b,x[k+3], S33,0xD4EF3085);
126 b=HH(b,c,d,a,x[k+6], S34,0x4881D05);
127 a=HH(a,b,c,d,x[k+9], S31,0xD9D4D039);
128 d=HH(d,a,b,c,x[k+12],S32,0xE6DB99E5);
129 c=HH(c,d,a,b,x[k+15],S33,0x1FA27CF8);
130 b=HH(b,c,d,a,x[k+2], S34,0xC4AC5665);
131 a=II(a,b,c,d,x[k+0], S41,0xF4292244);
132 d=II(d,a,b,c,x[k+7], S42,0x432AFF97);
133 c=II(c,d,a,b,x[k+14],S43,0xAB9423A7);
134 b=II(b,c,d,a,x[k+5], S44,0xFC93A039);
135 a=II(a,b,c,d,x[k+12],S41,0x655B59C3);
136 d=II(d,a,b,c,x[k+3], S42,0x8F0CCC92);
137 c=II(c,d,a,b,x[k+10],S43,0xFFEFF47D);
138 b=II(b,c,d,a,x[k+1], S44,0x85845DD1);
139 a=II(a,b,c,d,x[k+8], S41,0x6FA87E4F);
140 d=II(d,a,b,c,x[k+15],S42,0xFE2CE6E0);
141 c=II(c,d,a,b,x[k+6], S43,0xA3014314);
142 b=II(b,c,d,a,x[k+13],S44,0x4E0811A1);
143 a=II(a,b,c,d,x[k+4], S41,0xF7537E82);
144 d=II(d,a,b,c,x[k+11],S42,0xBD3AF235);
145 c=II(c,d,a,b,x[k+2], S43,0x2AD7D2BB);
146 b=II(b,c,d,a,x[k+9], S44,0xEB86D391);
147 a=AddUnsigned(a,AA); b=AddUnsigned(b,BB); c=AddUnsigned(c,CC); d=AddUnsigned(d,DD);
148 }
149 // Step 5. Output the 128 bit digest
150 var temp= WordToHex(a)+WordToHex(b)+WordToHex(c)+WordToHex(d);
151 return temp.toLowerCase();
152 }

测试HTML代码,如下:

 1 <html>
2 <head>
3 <script type="text/javascript" src="md5.js" charset="gbk"></script>
4 </head>
5 <body>
6 双击结果数据文本框,生成摘要数据</p>
7 加密数据:<input type=text id=myinput size="50"></p>
8 结果数据:<input type=text ondblclick='this.value=MD5(myinput.value)' size="50">
9 </body>
10 </html>

 

MD5 HTML及JS压缩包

以上摘要代码都经过测试,后台生成的数据和JS生成的数据完全可以对上(注:不可以有中文,有中文就不一致了)。

所有功能都实现后,我会将整个工程代码上传上来,供大家下载,暂时先不提供。

posted on 2012-03-28 12:08  ynjxxk  阅读(339)  评论(0编辑  收藏  举报