├── 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 | --------------------------------------------------------------------------------