├── JavaAlgorithmHelper
├── .classpath
├── .gitignore
├── .project
└── src
│ └── com
│ └── java
│ └── alogrithm
│ ├── Test.java
│ ├── helper
│ ├── AESHelper.java
│ ├── DESedeHelper.java
│ ├── RSAHelper.java
│ └── SignatureHelper.java
│ └── utils
│ ├── Base64.java
│ └── Hex.java
├── README.md
└── js
├── base64.js
├── des3.js
└── index.html
/JavaAlgorithmHelper/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/JavaAlgorithmHelper/.gitignore:
--------------------------------------------------------------------------------
1 | .settings
2 | bin
3 | PrivateKey
4 | PublicKey
--------------------------------------------------------------------------------
/JavaAlgorithmHelper/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | JavaAlgorithmHelper
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.jdt.core.javabuilder
10 |
11 |
12 |
13 |
14 |
15 | org.eclipse.jdt.core.javanature
16 |
17 |
18 |
--------------------------------------------------------------------------------
/JavaAlgorithmHelper/src/com/java/alogrithm/Test.java:
--------------------------------------------------------------------------------
1 | package com.java.alogrithm;
2 |
3 | import com.java.alogrithm.helper.AESHelper;
4 | import com.java.alogrithm.helper.DESedeHelper;
5 | import com.java.alogrithm.helper.SignatureHelper;
6 | import com.java.alogrithm.helper.RSAHelper;
7 | import com.java.alogrithm.utils.Hex;
8 |
9 | /**
10 | * HEX,AES,DESede,RSA,MD5等总测试
11 | *
12 | * @author steven-pan
13 | *
14 | */
15 | public class Test {
16 |
17 | /**
18 | * @param args
19 | *
20 | * @throws Exception
21 | */
22 | public static void main(String[] args) throws Exception {
23 | SignatureHelper.main(args);
24 | System.out.println("------------------------------------\n");
25 |
26 | Hex.main(args);
27 | System.out.println("------------------------------------\n");
28 |
29 | AESHelper.main(args);
30 | System.out.println("------------------------------------\n");
31 |
32 | DESedeHelper.main(args);
33 | System.out.println("------------------------------------\n");
34 |
35 | RSAHelper.main(args);
36 | System.out.println("------------------------------------\n");
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/JavaAlgorithmHelper/src/com/java/alogrithm/helper/AESHelper.java:
--------------------------------------------------------------------------------
1 | package com.java.alogrithm.helper;
2 |
3 | import java.security.NoSuchAlgorithmException;
4 |
5 | import javax.crypto.Cipher;
6 | import javax.crypto.NoSuchPaddingException;
7 | import javax.crypto.SecretKey;
8 | import javax.crypto.spec.SecretKeySpec;
9 |
10 | import com.java.alogrithm.utils.Base64;
11 |
12 |
13 | /**
14 | * AES算法加密,传输,解密过程示例(AES可以使用128、192、和256位密钥,并且用128位分组加密和解密数据)
15 | * JRE默认只能用16个字节(128)位密钥,
16 | * 使用密钥长度无限制模式:http://czj4451.iteye.com/blog/1986483
17 | * http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html
18 | * http://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html
19 | */
20 | public class AESHelper {
21 |
22 | private static Cipher cipher = null; // 私鈅加密对象Cipher
23 |
24 | public static void main(String args[]) {
25 | System.out.println("AES加解密测试:");
26 |
27 | String password = "c8a9229820ffa315bc6a17a9e43d01a9";
28 | String content = "6222001521522152212";
29 | // 加密(传输)
30 | System.out.println("加密前:" + content);
31 | byte[] encryptResult = encrypt(content, password);
32 |
33 | // 以HEX进行传输
34 | String codedtextb = Base64.encode(encryptResult);// data transfer as text
35 | System.out.println("Base64 format:" + codedtextb);
36 | encryptResult = Base64.decode(codedtextb);
37 |
38 | // 解密
39 | String decryptResultb = decrypt(encryptResult, password);
40 | System.out.println("解密后:" + decryptResultb);
41 | }
42 |
43 | static {
44 | try {
45 | cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
46 | } catch (NoSuchAlgorithmException e) {
47 | e.printStackTrace();
48 | } catch (NoSuchPaddingException e) {
49 | e.printStackTrace();
50 | }
51 | }
52 |
53 | /**
54 | * 加密
55 | *
56 | * @param message
57 | * @return
58 | */
59 | public static byte[] encrypt(String message, String passWord) {
60 | // if (passWord == null) {
61 | // System.out.print("passWord为空null");
62 | // return null;
63 | // }
64 | // // 判断passWord是否为16位
65 | // if (passWord.length() != 16) {
66 | // System.out.print("Key长度不是16位");
67 | // return null;
68 | // }
69 |
70 | try {
71 | /* AES算法 */
72 | SecretKey secretKey = new SecretKeySpec(passWord.getBytes(), "AES");// 获得密钥
73 | /* 获得一个私鈅加密类Cipher,DESede-》AES算法,ECB是加密模式,PKCS5Padding是填充方式 */
74 | cipher.init(Cipher.ENCRYPT_MODE, secretKey); // 设置工作模式为加密模式,给出密钥
75 | byte[] resultBytes = cipher.doFinal(message.getBytes("UTF-8")); // 正式执行加密操作
76 | return resultBytes;
77 | } catch (Exception e) {
78 | e.printStackTrace();
79 | }
80 | return null;
81 | }
82 |
83 | /**
84 | * 解密
85 | *
86 | * @param message
87 | * @return
88 | * @throws Exception
89 | */
90 | public static String decrypt(byte[] messageBytes, String passWord) {
91 | String result = "";
92 | try {
93 | /* AES算法 */
94 | SecretKey secretKey = new SecretKeySpec(passWord.getBytes(), "AES");// 获得密钥
95 | cipher.init(Cipher.DECRYPT_MODE, secretKey); // 设置工作模式为解密模式,给出密钥
96 | byte[] resultBytes = cipher.doFinal(messageBytes);// 正式执行解密操作
97 | result = new String(resultBytes, "UTF-8");
98 | } catch (Exception e) {
99 | e.printStackTrace();
100 | }
101 | return result;
102 | }
103 |
104 | /**
105 | * 去掉加密字符串换行符
106 | *
107 | * @param str
108 | * @return
109 | */
110 | public static String filter(String str) {
111 | String output = "";
112 | StringBuffer sb = new StringBuffer();
113 | for (int i = 0; i < str.length(); i++) {
114 | int asc = str.charAt(i);
115 | if (asc != 10 && asc != 13) {
116 | sb.append(str.subSequence(i, i + 1));
117 | }
118 | }
119 | output = new String(sb);
120 | return output;
121 | }
122 |
123 | }
124 |
--------------------------------------------------------------------------------
/JavaAlgorithmHelper/src/com/java/alogrithm/helper/DESedeHelper.java:
--------------------------------------------------------------------------------
1 | package com.java.alogrithm.helper;
2 |
3 | import java.security.MessageDigest;
4 | import java.util.Arrays;
5 |
6 | import javax.crypto.Cipher;
7 | import javax.crypto.SecretKey;
8 | import javax.crypto.spec.IvParameterSpec;
9 | import javax.crypto.spec.SecretKeySpec;
10 |
11 | import com.java.alogrithm.utils.Base64;
12 |
13 | /**
14 | * 3DES加解密
15 | *
16 | * @author steven-pan
17 | *
18 | */
19 | public class DESedeHelper {
20 |
21 | private static final String ALGORITHM_MD5 = "md5";
22 |
23 | private static final String ALGORITHM_DESEDE = "DESede";
24 |
25 | private static final String CIPHER_TRANSFORMATION = "DESede/CBC/PKCS5Padding";
26 |
27 | private static final String CHARSET_UTF_8 = "UTF-8";
28 |
29 | /**
30 | * test
31 | *
32 | * @param args
33 | * @throws Exception
34 | */
35 | public static void main(String[] args) throws Exception {
36 | System.out.println("DESede加解密测试:");
37 |
38 | final String privateKey = "HG58YZ3CR9HG58YZ3CR9HG58YZ3CR9";
39 |
40 | String text = "hello world!";// origin data
41 | System.out.println("加密前:" + text);
42 | byte[] codedtext = DESedeHelper.encrypt(text, privateKey);
43 |
44 | String codedtextb = Base64.encode(codedtext);// data transfer as text
45 | System.out.println("Base64 format:" + codedtextb);
46 | codedtext = Base64.decode(codedtextb);
47 |
48 | String decodedtext = DESedeHelper.decrypt(codedtext, privateKey);
49 | System.out.println("解密后:" + decodedtext); // This correctly shows "hello world!"
50 | }
51 |
52 | /**
53 | * encoded message
54 | *
55 | * @param message
56 | * origin message
57 | * @param sKey
58 | * origin privateKey
59 | * @return
60 | * @throws Exception
61 | */
62 | public static byte[] encrypt(String message, String sKey) throws Exception {
63 | final byte[] keyBytes = getKeyBytes(sKey);
64 |
65 | final SecretKey key = new SecretKeySpec(keyBytes, ALGORITHM_DESEDE);
66 | final IvParameterSpec iv = new IvParameterSpec(new byte[8]);
67 | final Cipher cipher = Cipher.getInstance(CIPHER_TRANSFORMATION);
68 | cipher.init(Cipher.ENCRYPT_MODE, key, iv);
69 |
70 | final byte[] plainTextBytes = message.getBytes(CHARSET_UTF_8);
71 | final byte[] cipherText = cipher.doFinal(plainTextBytes);
72 |
73 | return cipherText;
74 | }
75 |
76 | /**
77 | * decode from encoded message
78 | *
79 | * @param message
80 | * encoded message
81 | * @param sKey
82 | * origin privateKey
83 | * @return
84 | * @throws Exception
85 | */
86 | public static String decrypt(byte[] message, String sKey) throws Exception {
87 | final byte[] keyBytes = getKeyBytes(sKey);
88 |
89 | final SecretKey key = new SecretKeySpec(keyBytes, ALGORITHM_DESEDE);
90 | final IvParameterSpec iv = new IvParameterSpec(new byte[8]);
91 | final Cipher decipher = Cipher.getInstance(CIPHER_TRANSFORMATION);
92 | decipher.init(Cipher.DECRYPT_MODE, key, iv);
93 |
94 | final byte[] plainText = decipher.doFinal(message);
95 | return new String(plainText, CHARSET_UTF_8);
96 | }
97 |
98 | /**
99 | * generate keyBytes
100 | *
101 | * @param sKey
102 | * origin privateKey
103 | * @return
104 | * @throws Exception
105 | */
106 | private static byte[] getKeyBytes(String sKey) throws Exception {
107 | final MessageDigest md = MessageDigest.getInstance(ALGORITHM_MD5);
108 | final byte[] digestOfPassword = md.digest(sKey.getBytes(CHARSET_UTF_8));
109 | final byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24);
110 | for (int j = 0, k = 16; j < 8;) {
111 | keyBytes[k++] = keyBytes[j++];
112 | }
113 | return keyBytes;
114 | }
115 | }
--------------------------------------------------------------------------------
/JavaAlgorithmHelper/src/com/java/alogrithm/helper/RSAHelper.java:
--------------------------------------------------------------------------------
1 | package com.java.alogrithm.helper;
2 |
3 | import java.io.FileInputStream;
4 | import java.io.FileOutputStream;
5 | import java.io.ObjectInputStream;
6 | import java.io.ObjectOutputStream;
7 | import java.security.Key;
8 | import java.security.KeyPair;
9 | import java.security.KeyPairGenerator;
10 | import java.security.SecureRandom;
11 |
12 | import javax.crypto.Cipher;
13 |
14 | import com.java.alogrithm.utils.Base64;
15 |
16 | /**
17 | * RSA非对称加密算法。用法:1公钥加密(C),私钥解密(S);2私钥加密(S),公钥解密(C)。
18 | */
19 | public class RSAHelper {
20 |
21 | /** 指定加密算法为RSA */
22 | private static String ALGORITHM = "RSA";
23 |
24 | /** 指定key的大小 */
25 | private static int KEYSIZE = 1024;
26 |
27 | /** 指定公钥存放文件 */
28 | private static String PUBLIC_KEY_FILE = "PublicKey";
29 |
30 | /** 指定私钥存放文件 */
31 | private static String PRIVATE_KEY_FILE = "PrivateKey";
32 |
33 | public static void main(String[] args) throws Exception {
34 | System.out.println("RSA加解密测试:");
35 |
36 | generateKeyPair();
37 |
38 | final String source = "73C58BAFE578C59366D8C995CD0B9";// 要加密的字符串
39 | System.out.println("加密前:" + source);
40 |
41 | String cryptograph = encrypt(source);// 生成的密文
42 | System.out.println("Base64 format:" + cryptograph);
43 |
44 | String target = decrypt(cryptograph);// 解密密文
45 | System.out.println("解密后:" + target);
46 | }
47 |
48 | /**
49 | * 生成密钥对
50 | */
51 | private static void generateKeyPair() throws Exception {
52 | /** RSA算法要求有一个可信任的随机数源 */
53 | SecureRandom sr = new SecureRandom();
54 | /** 为RSA算法创建一个KeyPairGenerator对象 */
55 | KeyPairGenerator kpg = KeyPairGenerator.getInstance(ALGORITHM);
56 | /** 利用上面的随机数据源初始化这个KeyPairGenerator对象 */
57 | kpg.initialize(KEYSIZE, sr);
58 | /** 生成密匙对 */
59 | KeyPair kp = kpg.generateKeyPair();
60 | /** 得到公钥 */
61 | Key publicKey = kp.getPublic();
62 | /** 得到私钥 */
63 | Key privateKey = kp.getPrivate();
64 | /** 用对象流将生成的密钥写入文件 */
65 | ObjectOutputStream oos1 = new ObjectOutputStream(new FileOutputStream(PUBLIC_KEY_FILE));
66 | ObjectOutputStream oos2 = new ObjectOutputStream(new FileOutputStream(PRIVATE_KEY_FILE));
67 | oos1.writeObject(publicKey);
68 | oos2.writeObject(privateKey);
69 | /** 清空缓存,关闭文件输出流 */
70 | oos1.close();
71 | oos2.close();
72 | }
73 |
74 | /**
75 | * 加密方法 source: 源数据
76 | */
77 | public static String encrypt(String source) throws Exception {
78 | /** 将文件中的公钥对象读出 */
79 | ObjectInputStream ois = new ObjectInputStream(new FileInputStream(PUBLIC_KEY_FILE));
80 | Key key = (Key) ois.readObject();
81 | ois.close();
82 | /** 得到Cipher对象来实现对源数据的RSA加密 */
83 | Cipher cipher = Cipher.getInstance(ALGORITHM);
84 | cipher.init(Cipher.ENCRYPT_MODE, key);
85 | byte[] b = source.getBytes();
86 | /** 执行加密操作 */
87 | byte[] b1 = cipher.doFinal(b);
88 | return Base64.encode(b1);
89 | }
90 |
91 | /**
92 | * 解密算法 cryptograph:密文
93 | */
94 | public static String decrypt(String cryptograph) throws Exception {
95 | /** 将文件中的私钥对象读出 */
96 | ObjectInputStream ois = new ObjectInputStream(new FileInputStream(PRIVATE_KEY_FILE));
97 | Key key = (Key) ois.readObject();
98 | ois.close();
99 | /** 得到Cipher对象对已用公钥加密的数据进行RSA解密 */
100 | Cipher cipher = Cipher.getInstance(ALGORITHM);
101 | cipher.init(Cipher.DECRYPT_MODE, key);
102 | byte[] b1 = Base64.decode(cryptograph);
103 | /** 执行解密操作 */
104 | byte[] b = cipher.doFinal(b1);
105 | return new String(b);
106 | }
107 |
108 | }
--------------------------------------------------------------------------------
/JavaAlgorithmHelper/src/com/java/alogrithm/helper/SignatureHelper.java:
--------------------------------------------------------------------------------
1 | package com.java.alogrithm.helper;
2 |
3 | import java.io.File;
4 | import java.io.FileInputStream;
5 | import java.io.IOException;
6 | import java.security.InvalidKeyException;
7 | import java.security.MessageDigest;
8 | import java.text.SimpleDateFormat;
9 | import java.util.Comparator;
10 | import java.util.Date;
11 | import java.util.Locale;
12 | import java.util.Map;
13 | import java.util.TreeMap;
14 |
15 | import javax.crypto.Mac;
16 | import javax.crypto.spec.SecretKeySpec;
17 |
18 |
19 | import com.java.alogrithm.utils.Hex;
20 |
21 | /**
22 | * MD5, SHA-1等字符串签名工具
23 | *
24 | * @author steven-pan
25 | *
26 | */
27 | public class SignatureHelper {
28 | /**
29 | * algorithm: MD5
30 | */
31 | private static final String ALGORITHM_MD5 = "MD5";
32 |
33 | /**
34 | * algorithm: SHA-1
35 | */
36 | private static final String ALGORITHM_SHA1 = "SHA-1";
37 |
38 | /**
39 | * algorithm: HmacSHA1
40 | */
41 | private static final String HMAC_SHA1 = "HmacSHA1";
42 |
43 | /**
44 | * 对字符串取MD5值
45 | *
46 | * @param strInput
47 | * 输入字符串
48 | * @return
49 | */
50 | public static String encryptMD5(String strInput) {
51 | return encyptByAlogrithm(strInput, ALGORITHM_MD5);
52 | }
53 |
54 | /**
55 | * 取文件MD5值
56 | * @param file
57 | * @return
58 | */
59 | public static String encryptFileMD5(File file) {
60 | FileInputStream fis = null;
61 | MessageDigest md;
62 | try {
63 | md = MessageDigest.getInstance(ALGORITHM_MD5);
64 | fis = new FileInputStream(file);
65 | byte[] buffer = new byte[102400];
66 | int length;
67 | while ((length = fis.read(buffer)) != -1) {
68 | md.update(buffer, 0, length);
69 | }
70 | return Hex.encode(md.digest());
71 | } catch (Exception e) {
72 | return null;
73 | } finally {
74 | try {
75 | if (fis != null)
76 | fis.close();
77 | } catch (IOException e) {
78 | e.printStackTrace();
79 | }
80 | }
81 | }
82 |
83 | /**
84 | * 对字符串取SHA-1值
85 | *
86 | * @param strInput
87 | * 输入字符串
88 | * @return
89 | */
90 | public static String encryptSHA1(String strInput) {
91 | return encyptByAlogrithm(strInput, ALGORITHM_SHA1);
92 | }
93 |
94 | /**
95 | * 按输入算法名取摘要签名
96 | *
97 | * @param input
98 | * 输入字符串
99 | * @param alogrithm
100 | * 摘要算法名
101 | * @return
102 | */
103 | private static String encyptByAlogrithm(String input, String alogrithm) {
104 | try {
105 | java.security.MessageDigest md = java.security.MessageDigest
106 | .getInstance(alogrithm);
107 | md.update(input.getBytes("utf-8"));
108 | byte temp[] = md.digest();
109 | return Hex.encode(temp);
110 | } catch (Exception e) {
111 | e.printStackTrace();
112 | return null;
113 | }
114 | }
115 |
116 | /**
117 | * encode HmacSHA1
118 | *
119 | * @param data
120 | * @param key
121 | * @return
122 | */
123 | public static byte[] encodeHmacSHA1(final String data, final String key) {
124 | try {
125 | Mac mac = Mac.getInstance(HMAC_SHA1);
126 | SecretKeySpec spec = new SecretKeySpec(key.getBytes(), HMAC_SHA1);
127 | mac.init(spec);
128 | byte[] byteHMAC = mac.doFinal(data.getBytes());
129 | if (byteHMAC != null) {
130 | return byteHMAC;
131 | }
132 | } catch (InvalidKeyException e1) {
133 | e1.printStackTrace();
134 | } catch (Exception e2) {
135 | e2.printStackTrace();
136 | }
137 | return null;
138 | }
139 |
140 | /**
141 | * 获取byte数组加密值
142 | *
143 | * @param sortedArray
144 | * @param key
145 | * @param inputCharset
146 | * @return
147 | */
148 | public static String encryptMD5ByArray(String[] originalArray, String key) {
149 | String[] sortedArray = bubbleSort(originalArray);
150 | StringBuilder builder = new StringBuilder();
151 |
152 | for (int i = 0; i < sortedArray.length; i++) {
153 | if (i == sortedArray.length - 1) {
154 | builder.append(sortedArray[i]);
155 | } else {
156 | builder.append(sortedArray[i] + "&");
157 | }
158 | }
159 | builder.append(key);
160 | return encryptMD5(builder.toString());
161 | }
162 |
163 | /**
164 | * 数组排序(冒泡排序法)
165 | *
166 | * @param originalArray
167 | * @return
168 | */
169 | public static String[] bubbleSort(String[] originalArray) {
170 | int i, j;
171 | String temp;
172 | Boolean exchange;
173 |
174 | for (i = 0; i < originalArray.length; i++) {
175 | exchange = false;
176 | for (j = originalArray.length - 2; j >= i; j--) {
177 | if (originalArray[j + 1].compareTo(originalArray[j]) < 0) {
178 | temp = originalArray[j + 1];
179 | originalArray[j + 1] = originalArray[j];
180 | originalArray[j] = temp;
181 |
182 | exchange = true;
183 | }
184 | }
185 | if (!exchange) {
186 | break;
187 | }
188 | }
189 | return originalArray;
190 | }
191 |
192 |
193 | /**
194 | * 按key升序排序
195 | * @param map
196 | * @return
197 | */
198 | public static Map sortMapByKey(Map map) {
199 | if (map == null || map.isEmpty()) {
200 | return null;
201 | }
202 | Map sortMap = new TreeMap(new MapKeyComparator());
203 | sortMap.putAll(map);
204 | return sortMap;
205 | }
206 |
207 | public static class MapKeyComparator implements Comparator{
208 | public int compare(String str1, String str2) {
209 | return str1.compareTo(str2);
210 | }
211 | }
212 |
213 |
214 | /**
215 | * @param args
216 | * @throws Exception
217 | */
218 | public static void main(String[] args) throws Exception {
219 | System.out.println("MD5签名编测试:");
220 |
221 | final String key = "abcdefghijklmn";
222 | final String id = "0123456";
223 | Date date = new Date();
224 | SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS",
225 | Locale.CHINA);// 取请求时间
226 | // yyyy-MM-dd
227 | // HH:mm:ss.fff
228 | final String time = df.format(date);
229 | final String originArray[] = new String[] { "id=" + id, "time=" + time,
230 | "key=" + key };
231 | String digitalSign = encryptMD5ByArray(originArray, key);
232 | System.out.println("digitalSign:" + digitalSign);
233 |
234 | System.out.println(encryptMD5("abcv"));
235 | System.out.println(encryptSHA1("abcv"));
236 |
237 | System.out.println(Hex.encode(encodeHmacSHA1("abcv", "asdfasdafsf")));
238 | }
239 | }
240 |
--------------------------------------------------------------------------------
/JavaAlgorithmHelper/src/com/java/alogrithm/utils/Base64.java:
--------------------------------------------------------------------------------
1 | package com.java.alogrithm.utils;
2 |
3 | import java.io.ByteArrayOutputStream;
4 | import java.io.IOException;
5 | import java.io.OutputStream;
6 | import java.io.UnsupportedEncodingException;
7 |
8 | /**
9 | * Base64字符串与字节码转换工具
10 | *
11 | * @author steven-pan
12 | *
13 | */
14 | public class Base64 {
15 | private static final char[] legalChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray();
16 |
17 | /**
18 | * data[]进行编码
19 | * @param data
20 | * @return
21 | */
22 | public static String encode(byte[] data) {
23 | int start = 0;
24 | int len = data.length;
25 | StringBuffer buf = new StringBuffer(data.length * 3 / 2);
26 |
27 | int end = len - 3;
28 | int i = start;
29 | int n = 0;
30 |
31 | while (i <= end) {
32 | int d = ((((int) data[i]) & 0x0ff) << 16)
33 | | ((((int) data[i + 1]) & 0x0ff) << 8)
34 | | (((int) data[i + 2]) & 0x0ff);
35 | buf.append(legalChars[(d >> 18) & 63]);
36 | buf.append(legalChars[(d >> 12) & 63]);
37 | buf.append(legalChars[(d >> 6) & 63]);
38 | buf.append(legalChars[d & 63]);
39 | i += 3;
40 | if (n++ >= 14) {
41 | n = 0;
42 | buf.append(" ");
43 | }
44 | }
45 |
46 | if (i == start + len - 2) {
47 | int d = ((((int) data[i]) & 0x0ff) << 16)
48 | | ((((int) data[i + 1]) & 255) << 8);
49 | buf.append(legalChars[(d >> 18) & 63]);
50 | buf.append(legalChars[(d >> 12) & 63]);
51 | buf.append(legalChars[(d >> 6) & 63]);
52 | buf.append("=");
53 | } else if (i == start + len - 1) {
54 | int d = (((int) data[i]) & 0x0ff) << 16;
55 | buf.append(legalChars[(d >> 18) & 63]);
56 | buf.append(legalChars[(d >> 12) & 63]);
57 | buf.append("==");
58 | }
59 |
60 | return buf.toString();
61 | }
62 |
63 | private static int decode(char c) {
64 | if (c >= 'A' && c <= 'Z')
65 | return ((int) c) - 65;
66 | else if (c >= 'a' && c <= 'z')
67 | return ((int) c) - 97 + 26;
68 | else if (c >= '0' && c <= '9')
69 | return ((int) c) - 48 + 26 + 26;
70 | else
71 | switch (c) {
72 | case '+':
73 | return 62;
74 | case '/':
75 | return 63;
76 | case '=':
77 | return 0;
78 | default:
79 | throw new RuntimeException("unexpected code: " + c);
80 | }
81 | }
82 |
83 | /**
84 | * Decodes the given Base64 encoded String to a new byte array. The byte
85 | * array holding the decoded data is returned.
86 | */
87 |
88 | public static byte[] decode(String s) {
89 | ByteArrayOutputStream bos = new ByteArrayOutputStream();
90 | try {
91 | decode(s, bos);
92 | } catch (IOException e) {
93 | throw new RuntimeException();
94 | }
95 | byte[] decodedBytes = bos.toByteArray();
96 | try {
97 | bos.close();
98 | bos = null;
99 | } catch (IOException ex) {
100 | System.err.println("Error while decoding BASE64: " + ex.toString());
101 | }
102 | return decodedBytes;
103 | }
104 |
105 | private static void decode(String s, OutputStream os) throws IOException {
106 | int i = 0;
107 | int len = s.length();
108 | while (true) {
109 | while (i < len && s.charAt(i) <= ' ')
110 | i++;
111 | if (i == len)
112 | break;
113 | int tri = (decode(s.charAt(i)) << 18)
114 | + (decode(s.charAt(i + 1)) << 12)
115 | + (decode(s.charAt(i + 2)) << 6)
116 | + (decode(s.charAt(i + 3)));
117 | os.write((tri >> 16) & 255);
118 | if (s.charAt(i + 2) == '=')
119 | break;
120 | os.write((tri >> 8) & 255);
121 | if (s.charAt(i + 3) == '=')
122 | break;
123 | os.write(tri & 255);
124 | i += 4;
125 | }
126 | }
127 |
128 | /**
129 | * 去掉BASE64加密字符串换行符
130 | *
131 | * @param str
132 | * @return
133 | */
134 | public static String filter(String str) {
135 | String output = "";
136 | StringBuffer sb = new StringBuffer();
137 | for (int i = 0; i < str.length(); i++) {
138 | int asc = str.charAt(i);
139 | if (asc != 10 && asc != 13) {
140 | sb.append(str.subSequence(i, i + 1));
141 | }
142 | }
143 | output = new String(sb);
144 | return output;
145 | }
146 |
147 |
148 | public static void main(String[] args) {
149 | try {
150 | System.out.println(encode("asdssdfafasdfsw12345?@!#~#@#%#$%&%^*&&(&*)_()+()+sdfadsfsdfsfasd-*/878ssdfasdfasdfsadfsdafsadfasdfasdf".getBytes("UTF-8")));
151 | System.out.println(new String(decode("YXNkc3NkZmFmYXNkZnN3MTIzNDU/QCEjfiNAIyUjJCUmJV4qJiYoJiopXygp KygpK3NkZmFkc2ZzZGZzZmFzZC0qLzg3OHNzZGZhc2RmYXNkZnNhZGZzZGFm c2FkZmFzZGZhc2Rm"), "UTF-8"));
152 | } catch (UnsupportedEncodingException e) {
153 | // TODO Auto-generated catch block
154 | e.printStackTrace();
155 | }
156 | }
157 |
158 | // private static final char last2byte = (char) Integer
159 | // .parseInt("00000011", 2);
160 | //
161 | // private static final char last4byte = (char) Integer
162 | // .parseInt("00001111", 2);
163 | //
164 | // private static final char last6byte = (char) Integer
165 | // .parseInt("00111111", 2);
166 | //
167 | // private static final char lead6byte = (char) Integer
168 | // .parseInt("11111100", 2);
169 | //
170 | // private static final char lead4byte = (char) Integer
171 | // .parseInt("11110000", 2);
172 | //
173 | // private static final char lead2byte = (char) Integer
174 | // .parseInt("11000000", 2);
175 | //
176 | // private static final char[] encodeTable = new char[] { 'A', 'B', 'C', 'D',
177 | // 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q',
178 | // 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
179 | // 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
180 | // 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3',
181 | // '4', '5', '6', '7', '8', '9', '+', '/' };
182 | //
183 | //
184 | // public static String encode(byte[] from) {
185 | // StringBuffer to = new StringBuffer((int) (from.length * 1.34) + 3);
186 | // int num = 0;
187 | // char currentByte = 0;
188 | // for (int i = 0; i < from.length; i++) {
189 | // num = num % 8;
190 | // while (num < 8) {
191 | // switch (num) {
192 | // case 0:
193 | // currentByte = (char) (from[i] & lead6byte);
194 | // currentByte = (char) (currentByte >>> 2);
195 | // break;
196 | // case 2:
197 | // currentByte = (char) (from[i] & last6byte);
198 | // break;
199 | // case 4:
200 | // currentByte = (char) (from[i] & last4byte);
201 | // currentByte = (char) (currentByte << 2);
202 | // if ((i + 1) < from.length) {
203 | // currentByte |= (from[i + 1] & lead2byte) >>> 6;
204 | // }
205 | // break;
206 | // case 6:
207 | // currentByte = (char) (from[i] & last2byte);
208 | // currentByte = (char) (currentByte << 4);
209 | // if ((i + 1) < from.length) {
210 | // currentByte |= (from[i + 1] & lead4byte) >>> 4;
211 | // }
212 | // break;
213 | // }
214 | // to.append(encodeTable[currentByte]);
215 | // num += 6;
216 | // }
217 | // }
218 | // if (to.length() % 4 != 0) {
219 | // for (int i = 4 - to.length() % 4; i > 0; i--) {
220 | // to.append("=");
221 | // }
222 | // }
223 | // return to.toString();
224 | // }
225 |
226 | }
--------------------------------------------------------------------------------
/JavaAlgorithmHelper/src/com/java/alogrithm/utils/Hex.java:
--------------------------------------------------------------------------------
1 | package com.java.alogrithm.utils;
2 |
3 |
4 | /**
5 | * HEX字符串与字节码转换工具
6 | *
7 | * @author steven-pan
8 | *
9 | */
10 | public class Hex {
11 |
12 | /**
13 | * @param args
14 | * @throws Exception
15 | */
16 | public static void main(String[] args) throws Exception {
17 | System.out.println("HEX编解码测试:");
18 |
19 | final String input = "01234567890abcdefghijklmnopqrstuvwxyz";
20 | System.out.println("编码前:" + input);
21 |
22 | String hex = encode(input.getBytes("UTF-8"));
23 | System.out.println("HEX format:" + hex);
24 |
25 | byte[] hexbytes = deocde(hex);
26 | System.out.println("解密后:" + new String(hexbytes, "UTF-8"));
27 | }
28 |
29 | /**
30 | * 将16进制转换为二进制(服务端)
31 | *
32 | * @param hexStr
33 | * @return
34 | */
35 | public static byte[] deocde(String hexStr) {
36 | if (hexStr.length() < 1)
37 | return null;
38 | byte[] result = new byte[hexStr.length() / 2];
39 | for (int i = 0; i < hexStr.length() / 2; i++) {
40 | int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
41 | int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
42 | result[i] = (byte) (high * 16 + low);
43 | }
44 | return result;
45 | }
46 |
47 | /**
48 | * 将二进制转换成16进制
49 | *
50 | * @param buf
51 | * @return
52 | */
53 | public static String encode(byte buf[]) {
54 | StringBuffer sb = new StringBuffer();
55 | for (int i = 0; i < buf.length; i++) {
56 | String hex = Integer.toHexString(buf[i] & 0xFF);
57 | if (hex.length() == 1) {
58 | hex = '0' + hex;
59 | }
60 | sb.append(hex.toUpperCase());
61 | }
62 | return sb.toString();
63 | }
64 |
65 | }
66 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | JavaAlgorithmHelper
2 | ================================
3 |
4 | #### 1.说明
5 | Test.java:总测试程序。
6 | AESHelper.java:AES加解密工具。
7 | DESedeHelper.java:3DES加解密工具。
8 | RSAHelper.java:RSA加解密工具。
9 | SignatureHelper.java:MD5, SHA-1签名工具。
10 | Base64.java及Hex.java:字符串与字节码转换工具。
11 |
12 | #### 2.相关问题
13 | Base64如报错,请用security中的jar文件换掉JRE/lib/security中的jar包。
14 |
15 | ## License
16 |
17 | Licensed under the Apache License, Version 2.0 (the "License");
18 | you may not use this file except in compliance with the License.
19 | You may obtain a copy of the License at
20 |
21 | http://www.apache.org/licenses/LICENSE-2.0
22 |
23 | Unless required by applicable law or agreed to in writing, software
24 | distributed under the License is distributed on an "AS IS" BASIS,
25 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
26 | See the License for the specific language governing permissions and
27 | limitations under the License.
28 |
--------------------------------------------------------------------------------
/js/base64.js:
--------------------------------------------------------------------------------
1 | /**
2 | *create by 2014年7月9日 http://javascript.css-js.com/
3 | *BASE64 Encode and Decode By UTF-8 unicode
4 | *可以和java的BASE64编码和解码互相转化
5 | */
6 |
7 | var BASE64_MAPPING = [
8 | 'A','B','C','D','E','F','G','H',
9 | 'I','J','K','L','M','N','O','P',
10 | 'Q','R','S','T','U','V','W','X',
11 | 'Y','Z','a','b','c','d','e','f',
12 | 'g','h','i','j','k','l','m','n',
13 | 'o','p','q','r','s','t','u','v',
14 | 'w','x','y','z','0','1','2','3',
15 | '4','5','6','7','8','9','+','/'
16 | ];
17 |
18 | /**
19 | *ascii convert to binary
20 | */
21 | var _toBinary = function(ascii){
22 | var binary = new Array();
23 | while(ascii > 0){
24 | var b = ascii%2;
25 | ascii = Math.floor(ascii/2);
26 | binary.push(b);
27 | }
28 | /*
29 | var len = binary.length;
30 | if(6-len > 0){
31 | for(var i = 6-len ; i > 0 ; --i){
32 | binary.push(0);
33 | }
34 | }*/
35 | binary.reverse();
36 | return binary;
37 | };
38 |
39 | /**
40 | *binary convert to decimal
41 | */
42 | var _toDecimal = function(binary){
43 | var dec = 0;
44 | var p = 0;
45 | for(var i = binary.length-1 ; i >= 0 ; --i){
46 | var b = binary[i];
47 | if(b == 1){
48 | dec += Math.pow(2 , p);
49 | }
50 | ++p;
51 | }
52 | return dec;
53 | };
54 |
55 | /**
56 | *unicode convert to utf-8
57 | */
58 | var _toUTF8Binary = function(c , binaryArray){
59 | var mustLen = (8-(c+1)) + ((c-1)*6);
60 | var fatLen = binaryArray.length;
61 | var diff = mustLen - fatLen;
62 | while(--diff >= 0){
63 | binaryArray.unshift(0);
64 | }
65 | var binary = [];
66 | var _c = c;
67 | while(--_c >= 0){
68 | binary.push(1);
69 | }
70 | binary.push(0);
71 | var i = 0 , len = 8 - (c+1);
72 | for(; i < len ; ++i){
73 | binary.push(binaryArray[i]);
74 | }
75 |
76 | for(var j = 0 ; j < c-1 ; ++j){
77 | binary.push(1);
78 | binary.push(0);
79 | var sum = 6;
80 | while(--sum >= 0){
81 | binary.push(binaryArray[i++]);
82 | }
83 | }
84 | return binary;
85 | };
86 |
87 | var BASE64 = {
88 | /**
89 | *BASE64 Encode
90 | */
91 | encoder:function(str){
92 | var base64_Index = [];
93 | var binaryArray = [];
94 | for(var i = 0 , len = str.length ; i < len ; ++i){
95 | var unicode = str.charCodeAt(i);
96 | var _tmpBinary = _toBinary(unicode);
97 | if(unicode < 0x80){
98 | var _tmpdiff = 8 - _tmpBinary.length;
99 | while(--_tmpdiff >= 0){
100 | _tmpBinary.unshift(0);
101 | }
102 | binaryArray = binaryArray.concat(_tmpBinary);
103 | }else if(unicode >= 0x80 && unicode <= 0x7FF){
104 | binaryArray = binaryArray.concat(_toUTF8Binary(2 , _tmpBinary));
105 | }else if(unicode >= 0x800 && unicode <= 0xFFFF){//UTF-8 3byte
106 | binaryArray = binaryArray.concat(_toUTF8Binary(3 , _tmpBinary));
107 | }else if(unicode >= 0x10000 && unicode <= 0x1FFFFF){//UTF-8 4byte
108 | binaryArray = binaryArray.concat(_toUTF8Binary(4 , _tmpBinary));
109 | }else if(unicode >= 0x200000 && unicode <= 0x3FFFFFF){//UTF-8 5byte
110 | binaryArray = binaryArray.concat(_toUTF8Binary(5 , _tmpBinary));
111 | }else if(unicode >= 4000000 && unicode <= 0x7FFFFFFF){//UTF-8 6byte
112 | binaryArray = binaryArray.concat(_toUTF8Binary(6 , _tmpBinary));
113 | }
114 | }
115 |
116 | var extra_Zero_Count = 0;
117 | for(var i = 0 , len = binaryArray.length ; i < len ; i+=6){
118 | var diff = (i+6)-len;
119 | if(diff == 2){
120 | extra_Zero_Count = 2;
121 | }else if(diff == 4){
122 | extra_Zero_Count = 4;
123 | }
124 | //if(extra_Zero_Count > 0){
125 | // len += extra_Zero_Count+1;
126 | //}
127 | var _tmpExtra_Zero_Count = extra_Zero_Count;
128 | while(--_tmpExtra_Zero_Count >= 0){
129 | binaryArray.push(0);
130 | }
131 | base64_Index.push(_toDecimal(binaryArray.slice(i , i+6)));
132 | }
133 |
134 | var base64 = '';
135 | for(var i = 0 , len = base64_Index.length ; i < len ; ++i){
136 | base64 += BASE64_MAPPING[base64_Index[i]];
137 | }
138 |
139 | for(var i = 0 , len = extra_Zero_Count/2 ; i < len ; ++i){
140 | base64 += '=';
141 | }
142 | return base64;
143 | },
144 | /**
145 | *BASE64 Decode for UTF-8
146 | */
147 | decoder : function(_base64Str){
148 | var _len = _base64Str.length;
149 | var extra_Zero_Count = 0;
150 | /**
151 | *计算在进行BASE64编码的时候,补了几个0
152 | */
153 | if(_base64Str.charAt(_len-1) == '='){
154 | //alert(_base64Str.charAt(_len-1));
155 | //alert(_base64Str.charAt(_len-2));
156 | if(_base64Str.charAt(_len-2) == '='){//两个等号说明补了4个0
157 | extra_Zero_Count = 4;
158 | _base64Str = _base64Str.substring(0 , _len-2);
159 | }else{//一个等号说明补了2个0
160 | extra_Zero_Count = 2;
161 | _base64Str = _base64Str.substring(0 , _len - 1);
162 | }
163 | }
164 |
165 | var binaryArray = [];
166 | for(var i = 0 , len = _base64Str.length; i < len ; ++i){
167 | var c = _base64Str.charAt(i);
168 | for(var j = 0 , size = BASE64_MAPPING.length ; j < size ; ++j){
169 | if(c == BASE64_MAPPING[j]){
170 | var _tmp = _toBinary(j);
171 | /*不足6位的补0*/
172 | var _tmpLen = _tmp.length;
173 | if(6-_tmpLen > 0){
174 | for(var k = 6-_tmpLen ; k > 0 ; --k){
175 | _tmp.unshift(0);
176 | }
177 | }
178 | binaryArray = binaryArray.concat(_tmp);
179 | break;
180 | }
181 | }
182 | }
183 |
184 | if(extra_Zero_Count > 0){
185 | binaryArray = binaryArray.slice(0 , binaryArray.length - extra_Zero_Count);
186 | }
187 |
188 | var unicode = [];
189 | var unicodeBinary = [];
190 | for(var i = 0 , len = binaryArray.length ; i < len ; ){
191 | if(binaryArray[i] == 0){
192 | unicode=unicode.concat(_toDecimal(binaryArray.slice(i,i+8)));
193 | i += 8;
194 | }else{
195 | var sum = 0;
196 | while(i < len){
197 | if(binaryArray[i] == 1){
198 | ++sum;
199 | }else{
200 | break;
201 | }
202 | ++i;
203 | }
204 | unicodeBinary = unicodeBinary.concat(binaryArray.slice(i+1 , i+8-sum));
205 | i += 8 - sum;
206 | while(sum > 1){
207 | unicodeBinary = unicodeBinary.concat(binaryArray.slice(i+2 , i+8));
208 | i += 8;
209 | --sum;
210 | }
211 | unicode = unicode.concat(_toDecimal(unicodeBinary));
212 | unicodeBinary = [];
213 | }
214 | }
215 | //---------直接转换为结果
216 | var strResult = '';
217 | for(var i = 0 , len = unicode.length ; i < len ;++i){
218 | strResult += String.fromCharCode(unicode[i]);
219 | }
220 | return strResult;
221 | }
222 | };
--------------------------------------------------------------------------------
/js/des3.js:
--------------------------------------------------------------------------------
1 | /**
2 | * DES 加密算法
3 | *
4 | * 该函数接受一个 8 字节字符串作为普通 DES 算法的密钥(也就是 64 位,但是算法只使用 56 位),或者接受一个 24 字节字符串作为 3DES
5 | * 算法的密钥;第二个参数是要加密或解密的信息字符串;第三个布尔值参数用来说明信息是加密还是解密;接下来的可选参数 mode 如果是 0 表示 ECB
6 | * 模式,1 表示 CBC 模式,默认是 ECB 模式;最后一个可选项是一个 8 字节的输入向量字符串(在 ECB 模式下不使用)。返回的密文是字符串。
7 | *
8 | * 参数:
9 | * key: 8字节字符串作为普通 DES 算法的密钥,或 24 字节字符串作为 3DES
10 | * message: 加密或解密的信息字符串
11 | * encrypt: 布尔值参数用来说明信息是加密还是解密
12 | * mode: 1:CBC模式,0:ECB模式(默认)
13 | * iv:
14 | * padding: 可选项, 8字节的输入向量字符串(在 ECB 模式下不使用)
15 | */
16 | //des http://www.cnblogs.com/bullub/archive/2013/05/02/3054798.html
17 | //this takes the key, the message, and whether to encrypt or decrypt
18 | function des (key, message, encrypt, mode, iv, padding) {
19 | if(encrypt) //如果是加密的话,首先转换编码
20 | message = unescape(encodeURIComponent(message));
21 | //declaring this locally speeds things up a bit
22 | var spfunction1 = new Array (0x1010400,0,0x10000,0x1010404,0x1010004,0x10404,0x4,0x10000,0x400,0x1010400,0x1010404,0x400,0x1000404,0x1010004,0x1000000,0x4,0x404,0x1000400,0x1000400,0x10400,0x10400,0x1010000,0x1010000,0x1000404,0x10004,0x1000004,0x1000004,0x10004,0,0x404,0x10404,0x1000000,0x10000,0x1010404,0x4,0x1010000,0x1010400,0x1000000,0x1000000,0x400,0x1010004,0x10000,0x10400,0x1000004,0x400,0x4,0x1000404,0x10404,0x1010404,0x10004,0x1010000,0x1000404,0x1000004,0x404,0x10404,0x1010400,0x404,0x1000400,0x1000400,0,0x10004,0x10400,0,0x1010004);
23 | var spfunction2 = new Array (-0x7fef7fe0,-0x7fff8000,0x8000,0x108020,0x100000,0x20,-0x7fefffe0,-0x7fff7fe0,-0x7fffffe0,-0x7fef7fe0,-0x7fef8000,-0x80000000,-0x7fff8000,0x100000,0x20,-0x7fefffe0,0x108000,0x100020,-0x7fff7fe0,0,-0x80000000,0x8000,0x108020,-0x7ff00000,0x100020,-0x7fffffe0,0,0x108000,0x8020,-0x7fef8000,-0x7ff00000,0x8020,0,0x108020,-0x7fefffe0,0x100000,-0x7fff7fe0,-0x7ff00000,-0x7fef8000,0x8000,-0x7ff00000,-0x7fff8000,0x20,-0x7fef7fe0,0x108020,0x20,0x8000,-0x80000000,0x8020,-0x7fef8000,0x100000,-0x7fffffe0,0x100020,-0x7fff7fe0,-0x7fffffe0,0x100020,0x108000,0,-0x7fff8000,0x8020,-0x80000000,-0x7fefffe0,-0x7fef7fe0,0x108000);
24 | var spfunction3 = new Array (0x208,0x8020200,0,0x8020008,0x8000200,0,0x20208,0x8000200,0x20008,0x8000008,0x8000008,0x20000,0x8020208,0x20008,0x8020000,0x208,0x8000000,0x8,0x8020200,0x200,0x20200,0x8020000,0x8020008,0x20208,0x8000208,0x20200,0x20000,0x8000208,0x8,0x8020208,0x200,0x8000000,0x8020200,0x8000000,0x20008,0x208,0x20000,0x8020200,0x8000200,0,0x200,0x20008,0x8020208,0x8000200,0x8000008,0x200,0,0x8020008,0x8000208,0x20000,0x8000000,0x8020208,0x8,0x20208,0x20200,0x8000008,0x8020000,0x8000208,0x208,0x8020000,0x20208,0x8,0x8020008,0x20200);
25 | var spfunction4 = new Array (0x802001,0x2081,0x2081,0x80,0x802080,0x800081,0x800001,0x2001,0,0x802000,0x802000,0x802081,0x81,0,0x800080,0x800001,0x1,0x2000,0x800000,0x802001,0x80,0x800000,0x2001,0x2080,0x800081,0x1,0x2080,0x800080,0x2000,0x802080,0x802081,0x81,0x800080,0x800001,0x802000,0x802081,0x81,0,0,0x802000,0x2080,0x800080,0x800081,0x1,0x802001,0x2081,0x2081,0x80,0x802081,0x81,0x1,0x2000,0x800001,0x2001,0x802080,0x800081,0x2001,0x2080,0x800000,0x802001,0x80,0x800000,0x2000,0x802080);
26 | var spfunction5 = new Array (0x100,0x2080100,0x2080000,0x42000100,0x80000,0x100,0x40000000,0x2080000,0x40080100,0x80000,0x2000100,0x40080100,0x42000100,0x42080000,0x80100,0x40000000,0x2000000,0x40080000,0x40080000,0,0x40000100,0x42080100,0x42080100,0x2000100,0x42080000,0x40000100,0,0x42000000,0x2080100,0x2000000,0x42000000,0x80100,0x80000,0x42000100,0x100,0x2000000,0x40000000,0x2080000,0x42000100,0x40080100,0x2000100,0x40000000,0x42080000,0x2080100,0x40080100,0x100,0x2000000,0x42080000,0x42080100,0x80100,0x42000000,0x42080100,0x2080000,0,0x40080000,0x42000000,0x80100,0x2000100,0x40000100,0x80000,0,0x40080000,0x2080100,0x40000100);
27 | var spfunction6 = new Array (0x20000010,0x20400000,0x4000,0x20404010,0x20400000,0x10,0x20404010,0x400000,0x20004000,0x404010,0x400000,0x20000010,0x400010,0x20004000,0x20000000,0x4010,0,0x400010,0x20004010,0x4000,0x404000,0x20004010,0x10,0x20400010,0x20400010,0,0x404010,0x20404000,0x4010,0x404000,0x20404000,0x20000000,0x20004000,0x10,0x20400010,0x404000,0x20404010,0x400000,0x4010,0x20000010,0x400000,0x20004000,0x20000000,0x4010,0x20000010,0x20404010,0x404000,0x20400000,0x404010,0x20404000,0,0x20400010,0x10,0x4000,0x20400000,0x404010,0x4000,0x400010,0x20004010,0,0x20404000,0x20000000,0x400010,0x20004010);
28 | var spfunction7 = new Array (0x200000,0x4200002,0x4000802,0,0x800,0x4000802,0x200802,0x4200800,0x4200802,0x200000,0,0x4000002,0x2,0x4000000,0x4200002,0x802,0x4000800,0x200802,0x200002,0x4000800,0x4000002,0x4200000,0x4200800,0x200002,0x4200000,0x800,0x802,0x4200802,0x200800,0x2,0x4000000,0x200800,0x4000000,0x200800,0x200000,0x4000802,0x4000802,0x4200002,0x4200002,0x2,0x200002,0x4000000,0x4000800,0x200000,0x4200800,0x802,0x200802,0x4200800,0x802,0x4000002,0x4200802,0x4200000,0x200800,0,0x2,0x4200802,0,0x200802,0x4200000,0x800,0x4000002,0x4000800,0x800,0x200002);
29 | var spfunction8 = new Array (0x10001040,0x1000,0x40000,0x10041040,0x10000000,0x10001040,0x40,0x10000000,0x40040,0x10040000,0x10041040,0x41000,0x10041000,0x41040,0x1000,0x40,0x10040000,0x10000040,0x10001000,0x1040,0x41000,0x40040,0x10040040,0x10041000,0x1040,0,0,0x10040040,0x10000040,0x10001000,0x41040,0x40000,0x41040,0x40000,0x10041000,0x1000,0x40,0x10040040,0x1000,0x41040,0x10001000,0x40,0x10000040,0x10040000,0x10040040,0x10000000,0x40000,0x10001040,0,0x10041040,0x40040,0x10000040,0x10040000,0x10001000,0x10001040,0,0x10041040,0x41000,0x41000,0x1040,0x1040,0x40040,0x10000000,0x10041000);
30 |
31 | //create the 16 or 48 subkeys we will need
32 | var keys = des_createKeys (key);
33 | var m=0, i, j, temp, temp2, right1, right2, left, right, looping;
34 | var cbcleft, cbcleft2, cbcright, cbcright2
35 | var endloop, loopinc;
36 | var len = message.length;
37 | var chunk = 0;
38 | //set up the loops for single and triple des
39 | var iterations = keys.length == 32 ? 3 : 9; //single or triple des
40 | if (iterations == 3) {looping = encrypt ? new Array (0, 32, 2) : new Array (30, -2, -2);}
41 | else {looping = encrypt ? new Array (0, 32, 2, 62, 30, -2, 64, 96, 2) : new Array (94, 62, -2, 32, 64, 2, 30, -2, -2);}
42 |
43 | //pad the message depending on the padding parameter
44 | if (padding == 2) message += " "; //pad the message with spaces
45 | else if (padding == 1) {
46 | if(encrypt) {
47 | temp = 8-(len%8);
48 | message += String.fromCharCode(temp,temp,temp,temp,temp,temp,temp,temp);
49 | if (temp===8) len+=8;
50 | }
51 | } //PKCS7 padding
52 | else if (!padding) message += "\0\0\0\0\0\0\0\0"; //pad the message out with null bytes
53 |
54 | //store the result here
55 | var result = "";
56 | var tempresult = "";
57 |
58 | if (mode == 1) { //CBC mode
59 | cbcleft = (iv.charCodeAt(m++) << 24) | (iv.charCodeAt(m++) << 16) | (iv.charCodeAt(m++) << 8) | iv.charCodeAt(m++);
60 | cbcright = (iv.charCodeAt(m++) << 24) | (iv.charCodeAt(m++) << 16) | (iv.charCodeAt(m++) << 8) | iv.charCodeAt(m++);
61 | m=0;
62 | }
63 |
64 | //loop through each 64 bit chunk of the message
65 | while (m < len) {
66 | left = (message.charCodeAt(m++) << 24) | (message.charCodeAt(m++) << 16) | (message.charCodeAt(m++) << 8) | message.charCodeAt(m++);
67 | right = (message.charCodeAt(m++) << 24) | (message.charCodeAt(m++) << 16) | (message.charCodeAt(m++) << 8) | message.charCodeAt(m++);
68 |
69 | //for Cipher Block Chaining mode, xor the message with the previous result
70 | if (mode == 1) {if (encrypt) {left ^= cbcleft; right ^= cbcright;} else {cbcleft2 = cbcleft; cbcright2 = cbcright; cbcleft = left; cbcright = right;}}
71 |
72 | //first each 64 but chunk of the message must be permuted according to IP
73 | temp = ((left >>> 4) ^ right) & 0x0f0f0f0f; right ^= temp; left ^= (temp << 4);
74 | temp = ((left >>> 16) ^ right) & 0x0000ffff; right ^= temp; left ^= (temp << 16);
75 | temp = ((right >>> 2) ^ left) & 0x33333333; left ^= temp; right ^= (temp << 2);
76 | temp = ((right >>> 8) ^ left) & 0x00ff00ff; left ^= temp; right ^= (temp << 8);
77 | temp = ((left >>> 1) ^ right) & 0x55555555; right ^= temp; left ^= (temp << 1);
78 |
79 | left = ((left << 1) | (left >>> 31));
80 | right = ((right << 1) | (right >>> 31));
81 |
82 | //do this either 1 or 3 times for each chunk of the message
83 | for (j=0; j>> 4) | (right << 28)) ^ keys[i+1];
90 | //the result is attained by passing these bytes through the S selection functions
91 | temp = left;
92 | left = right;
93 | right = temp ^ (spfunction2[(right1 >>> 24) & 0x3f] | spfunction4[(right1 >>> 16) & 0x3f]
94 | | spfunction6[(right1 >>> 8) & 0x3f] | spfunction8[right1 & 0x3f]
95 | | spfunction1[(right2 >>> 24) & 0x3f] | spfunction3[(right2 >>> 16) & 0x3f]
96 | | spfunction5[(right2 >>> 8) & 0x3f] | spfunction7[right2 & 0x3f]);
97 | }
98 | temp = left; left = right; right = temp; //unreverse left and right
99 | } //for either 1 or 3 iterations
100 |
101 | //move then each one bit to the right
102 | left = ((left >>> 1) | (left << 31));
103 | right = ((right >>> 1) | (right << 31));
104 |
105 | //now perform IP-1, which is IP in the opposite direction
106 | temp = ((left >>> 1) ^ right) & 0x55555555; right ^= temp; left ^= (temp << 1);
107 | temp = ((right >>> 8) ^ left) & 0x00ff00ff; left ^= temp; right ^= (temp << 8);
108 | temp = ((right >>> 2) ^ left) & 0x33333333; left ^= temp; right ^= (temp << 2);
109 | temp = ((left >>> 16) ^ right) & 0x0000ffff; right ^= temp; left ^= (temp << 16);
110 | temp = ((left >>> 4) ^ right) & 0x0f0f0f0f; right ^= temp; left ^= (temp << 4);
111 |
112 | //for Cipher Block Chaining mode, xor the message with the previous result
113 | if (mode == 1) {if (encrypt) {cbcleft = left; cbcright = right;} else {left ^= cbcleft2; right ^= cbcright2;}}
114 | tempresult += String.fromCharCode ((left>>>24), ((left>>>16) & 0xff), ((left>>>8) & 0xff), (left & 0xff), (right>>>24), ((right>>>16) & 0xff), ((right>>>8) & 0xff), (right & 0xff));
115 |
116 | chunk += 8;
117 | if (chunk == 512) {result += tempresult; tempresult = ""; chunk = 0;}
118 | } //for every 8 characters, or 64 bits in the message
119 |
120 | //return the result as an array
121 | result += tempresult;
122 | result = result.replace(/\0*$/g, "");
123 |
124 | if(!encrypt ) { //如果是解密的话,解密结束后对PKCS7 padding进行解码,并转换成utf-8编码
125 | if(padding === 1) { //PKCS7 padding解码
126 | var len = result.length, paddingChars = 0;
127 | len && (paddingChars = result.charCodeAt(len-1));
128 | (paddingChars <= 8) && (result = result.substring(0, len - paddingChars));
129 | }
130 | //转换成UTF-8编码
131 | result = decodeURIComponent(escape(result));
132 | }
133 |
134 | return result;
135 | } //end of des
136 |
137 |
138 |
139 | //des_createKeys
140 | //this takes as input a 64 bit key (even though only 56 bits are used)
141 | //as an array of 2 integers, and returns 16 48 bit keys
142 | function des_createKeys (key) {
143 | //declaring this locally speeds things up a bit
144 | var pc2bytes0 = new Array (0,0x4,0x20000000,0x20000004,0x10000,0x10004,0x20010000,0x20010004,0x200,0x204,0x20000200,0x20000204,0x10200,0x10204,0x20010200,0x20010204);
145 | var pc2bytes1 = new Array (0,0x1,0x100000,0x100001,0x4000000,0x4000001,0x4100000,0x4100001,0x100,0x101,0x100100,0x100101,0x4000100,0x4000101,0x4100100,0x4100101);
146 | var pc2bytes2 = new Array (0,0x8,0x800,0x808,0x1000000,0x1000008,0x1000800,0x1000808,0,0x8,0x800,0x808,0x1000000,0x1000008,0x1000800,0x1000808);
147 | var pc2bytes3 = new Array (0,0x200000,0x8000000,0x8200000,0x2000,0x202000,0x8002000,0x8202000,0x20000,0x220000,0x8020000,0x8220000,0x22000,0x222000,0x8022000,0x8222000);
148 | var pc2bytes4 = new Array (0,0x40000,0x10,0x40010,0,0x40000,0x10,0x40010,0x1000,0x41000,0x1010,0x41010,0x1000,0x41000,0x1010,0x41010);
149 | var pc2bytes5 = new Array (0,0x400,0x20,0x420,0,0x400,0x20,0x420,0x2000000,0x2000400,0x2000020,0x2000420,0x2000000,0x2000400,0x2000020,0x2000420);
150 | var pc2bytes6 = new Array (0,0x10000000,0x80000,0x10080000,0x2,0x10000002,0x80002,0x10080002,0,0x10000000,0x80000,0x10080000,0x2,0x10000002,0x80002,0x10080002);
151 | var pc2bytes7 = new Array (0,0x10000,0x800,0x10800,0x20000000,0x20010000,0x20000800,0x20010800,0x20000,0x30000,0x20800,0x30800,0x20020000,0x20030000,0x20020800,0x20030800);
152 | var pc2bytes8 = new Array (0,0x40000,0,0x40000,0x2,0x40002,0x2,0x40002,0x2000000,0x2040000,0x2000000,0x2040000,0x2000002,0x2040002,0x2000002,0x2040002);
153 | var pc2bytes9 = new Array (0,0x10000000,0x8,0x10000008,0,0x10000000,0x8,0x10000008,0x400,0x10000400,0x408,0x10000408,0x400,0x10000400,0x408,0x10000408);
154 | var pc2bytes10 = new Array (0,0x20,0,0x20,0x100000,0x100020,0x100000,0x100020,0x2000,0x2020,0x2000,0x2020,0x102000,0x102020,0x102000,0x102020);
155 | var pc2bytes11 = new Array (0,0x1000000,0x200,0x1000200,0x200000,0x1200000,0x200200,0x1200200,0x4000000,0x5000000,0x4000200,0x5000200,0x4200000,0x5200000,0x4200200,0x5200200);
156 | var pc2bytes12 = new Array (0,0x1000,0x8000000,0x8001000,0x80000,0x81000,0x8080000,0x8081000,0x10,0x1010,0x8000010,0x8001010,0x80010,0x81010,0x8080010,0x8081010);
157 | var pc2bytes13 = new Array (0,0x4,0x100,0x104,0,0x4,0x100,0x104,0x1,0x5,0x101,0x105,0x1,0x5,0x101,0x105);
158 |
159 | //how many iterations (1 for des, 3 for triple des)
160 | var iterations = key.length > 8 ? 3 : 1; //changed by Paul 16/6/2007 to use Triple DES for 9+ byte keys
161 | //stores the return keys
162 | var keys = new Array (32 * iterations);
163 | //now define the left shifts which need to be done
164 | var shifts = new Array (0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0);
165 | //other variables
166 | var lefttemp, righttemp, m=0, n=0, temp;
167 |
168 | for (var j=0; j>> 4) ^ right) & 0x0f0f0f0f; right ^= temp; left ^= (temp << 4);
173 | temp = ((right >>> -16) ^ left) & 0x0000ffff; left ^= temp; right ^= (temp << -16);
174 | temp = ((left >>> 2) ^ right) & 0x33333333; right ^= temp; left ^= (temp << 2);
175 | temp = ((right >>> -16) ^ left) & 0x0000ffff; left ^= temp; right ^= (temp << -16);
176 | temp = ((left >>> 1) ^ right) & 0x55555555; right ^= temp; left ^= (temp << 1);
177 | temp = ((right >>> 8) ^ left) & 0x00ff00ff; left ^= temp; right ^= (temp << 8);
178 | temp = ((left >>> 1) ^ right) & 0x55555555; right ^= temp; left ^= (temp << 1);
179 |
180 | //the right side needs to be shifted and to get the last four bits of the left side
181 | temp = (left << 8) | ((right >>> 20) & 0x000000f0);
182 | //left needs to be put upside down
183 | left = (right << 24) | ((right << 8) & 0xff0000) | ((right >>> 8) & 0xff00) | ((right >>> 24) & 0xf0);
184 | right = temp;
185 |
186 | //now go through and perform these shifts on the left and right keys
187 | for (var i=0; i < shifts.length; i++) {
188 | //shift the keys either one or two bits to the left
189 | if (shifts[i]) {left = (left << 2) | (left >>> 26); right = (right << 2) | (right >>> 26);}
190 | else {left = (left << 1) | (left >>> 27); right = (right << 1) | (right >>> 27);}
191 | left &= -0xf; right &= -0xf;
192 |
193 | //now apply PC-2, in such a way that E is easier when encrypting or decrypting
194 | //this conversion will look like PC-2 except only the last 6 bits of each byte are used
195 | //rather than 48 consecutive bits and the order of lines will be according to
196 | //how the S selection functions will be applied: S2, S4, S6, S8, S1, S3, S5, S7
197 | lefttemp = pc2bytes0[left >>> 28] | pc2bytes1[(left >>> 24) & 0xf]
198 | | pc2bytes2[(left >>> 20) & 0xf] | pc2bytes3[(left >>> 16) & 0xf]
199 | | pc2bytes4[(left >>> 12) & 0xf] | pc2bytes5[(left >>> 8) & 0xf]
200 | | pc2bytes6[(left >>> 4) & 0xf];
201 | righttemp = pc2bytes7[right >>> 28] | pc2bytes8[(right >>> 24) & 0xf]
202 | | pc2bytes9[(right >>> 20) & 0xf] | pc2bytes10[(right >>> 16) & 0xf]
203 | | pc2bytes11[(right >>> 12) & 0xf] | pc2bytes12[(right >>> 8) & 0xf]
204 | | pc2bytes13[(right >>> 4) & 0xf];
205 | temp = ((righttemp >>> 16) ^ lefttemp) & 0x0000ffff;
206 | keys[n++] = lefttemp ^ temp; keys[n++] = righttemp ^ (temp << 16);
207 | }
208 | } //for each iterations
209 | //return the keys we've created
210 | return keys;
211 | } //end of des_createKeys
212 | function genkey(key, start, end) {
213 | //8 byte / 64 bit Key (DES) or 192 bit Key
214 | return {key:pad(key.slice(start, end)),vector: 1};
215 | }
216 | function pad(key) {
217 | for (var i = key.length; i<24; i++) {
218 | key+="0";
219 | }
220 | return key;
221 | }
222 |
223 | var des3iv = '12345678';
224 | var DES3 = {
225 | //3DES加密,CBC/PKCS5Padding
226 | encrypt:function(key,input){
227 | var genKey = genkey(key, 0, 24);
228 | return btoa(des(genKey.key, input, 1, 1, des3iv, 1));
229 | },
230 | ////3DES解密,CBC/PKCS5Padding
231 | decrypt:function(key,input){
232 | var genKey = genkey(key, 0, 24);
233 | return des(genKey.key, atob(input), 0, 1, des3iv, 1);
234 | }
235 | };
--------------------------------------------------------------------------------
/js/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | BASE64编码
5 |
6 |
7 |
8 |
9 |
10 |
11 |
29 |
30 |
31 |
--------------------------------------------------------------------------------