AES、DES加解密方法(Java和JS编程)

在项目中经常会对一些比较隐私的内容进行加密后再传输,比如登录密码、个人信息等;

DES和AES是目前两种比较常用的对称加密算法;

(此篇不讲原理,想了解原理可参考:DES算法AES算法

一、JS实现方式:

需要引入JavaScript加密库-CryptoJS

1.DES加密以及解密:

 1 //DES 加密
 2 function encryptByDES(message, key) {
 3     var keyHex = CryptoJS.enc.Utf8.parse(key);
 4     var encrypted = CryptoJS.DES.encrypt(message, keyHex, {
 5         mode: CryptoJS.mode.ECB,
 6         padding: CryptoJS.pad.Pkcs7
 7     });
 8     return encrypted.toString();
 9 }
10 //DES 解密
11 function decryptByDES(ciphertext, key) {
12     var keyHex = CryptoJS.enc.Utf8.parse(key);
13     // direct decrypt ciphertext
14     var decrypted = CryptoJS.DES.decrypt({
15         ciphertext: CryptoJS.enc.Base64.parse(ciphertext)
16     }, keyHex, {
17         mode: CryptoJS.mode.ECB,
18         padding: CryptoJS.pad.Pkcs7
19     });
20     return decrypted.toString(CryptoJS.enc.Utf8);
21 }

2.AES加密以及解密:

 1 //AES 加密
 2 function encryptByAES(message, key) {
 3     var keyHex = CryptoJS.enc.Utf8.parse(key);
 4     var encrypted = CryptoJS.AES.encrypt(message, keyHex, {
 5         mode: CryptoJS.mode.ECB,
 6         padding: CryptoJS.pad.Pkcs7
 7     });
 8     return encrypted.toString();
 9 }
10 //AES 解密
11 function decryptByAES(ciphertext, key) {
12     var keyHex = CryptoJS.enc.Utf8.parse(key);
13     // direct decrypt ciphertext
14     var decrypted = CryptoJS.AES.decrypt({
15         ciphertext: CryptoJS.enc.Base64.parse(ciphertext)
16     }, keyHex, {
17         mode: CryptoJS.mode.ECB,
18         padding: CryptoJS.pad.Pkcs7
19     });
20     return decrypted.toString(CryptoJS.enc.Utf8);
21 }

二、Java实现

Java有两种AES加密实现方式:

1.使用AES-128-ECB加密模式,秘钥必须为16位字符串(128bit = 16 * 8bit);这种方式与上面JS的AES可以前后端配合一起使用;

 1 // 加密
 2 public static String Encrypt(String sSrc, String sKey) throws Exception {
 3     if (sKey == null) {
 4         System.out.print("Key为空null");
 5         return null;
 6     }
 7     // 判断Key是否为16位
 8     if (sKey.length() != 16) {
 9         System.out.print("Key长度不是16位");
10         return null;
11     }
12     byte[] raw = sKey.getBytes("utf-8");
13     SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
14     Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");//"算法/模式/补码方式"
15     cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
16     byte[] encrypted = cipher.doFinal(sSrc.getBytes("utf-8"));
17     //此处使用BASE64做转码功能,同时能起到2次加密的作用。
18     //return new Base64().encodeToString(encrypted);
19     return Base64.encode(encrypted);
20 }
21 
22 // 解密
23 public static String Decrypt(String sSrc, String sKey) throws Exception {
24     try {
25         // 判断Key是否正确
26         if (sKey == null) {
27             System.out.print("Key为空null");
28             return null;
29         }
30         // 判断Key是否为16位
31         if (sKey.length() != 16) {
32             System.out.print("Key长度不是16位");
33             return null;
34         }
35         byte[] raw = sKey.getBytes("utf-8");
36         SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
37         Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
38         cipher.init(Cipher.DECRYPT_MODE, skeySpec);
39         //先用base64转码
40         //byte[] encrypted1 = new Base64().decode(sSrc);
41         byte[] encrypted1 = Base64.decode(sSrc);
42         try {
43             byte[] original = cipher.doFinal(encrypted1);
44             String originalString = new String(original,"utf-8");
45             return originalString;
46         } catch (Exception e) {
47             System.out.println(e.toString());
48             return null;
49         }
50     } catch (Exception ex) {
51         System.out.println(ex.toString());
52         return null;
53     }
54 }

2.下面这种方式对加密解密的秘钥没有长度限制(代码中进行了补全到相应位数),但不能和JS的实现配合使用,将算法名称和秘钥的编码位数进行更改就变为了DES加密

 1 //加密
 2 public static String encrypt(String content, String password) {  
 3     try {
 4         //将秘钥补全为128位
 5         KeyGenerator kgen = KeyGenerator.getInstance("AES");
 6         //若想改为DES加密,则需要将秘钥位数改为64位
 7         kgen.init(128, new SecureRandom(password.getBytes()));
 8         SecretKey secretKey = kgen.generateKey();  
 9         byte[] enCodeFormat = secretKey.getEncoded();  
10         SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
11         //创建密码器
12         Cipher cipher = Cipher.getInstance("AES");
13         byte[] byteContent = content.getBytes("utf-8");
14         //初始化  
15         cipher.init(Cipher.ENCRYPT_MODE, key);
16         //加密 
17         byte[] result = cipher.doFinal(byteContent);
18         //Base64转码
19         return Base64.encode(result); 
20     } catch (NoSuchAlgorithmException e) {  
21         e.printStackTrace();  
22     } catch (NoSuchPaddingException e) {  
23         e.printStackTrace();  
24     } catch (InvalidKeyException e) {  
25         e.printStackTrace();  
26     } catch (UnsupportedEncodingException e) {  
27         e.printStackTrace();  
28     } catch (IllegalBlockSizeException e) {  
29         e.printStackTrace();  
30     } catch (BadPaddingException e) {  
31         e.printStackTrace();  
32     }  
33     return null;
34 }
35 
36 //解密
37 public static String decrypt(String content, String password) throws Exception {  
38     try {
39         //将秘钥补全为128位
40         KeyGenerator kgen = KeyGenerator.getInstance("AES");
41         //若想改为DES加密,则需要将秘钥位数改为64位
42         kgen.init(128, new SecureRandom(password.getBytes()));  
43         SecretKey secretKey = kgen.generateKey();  
44         byte[] enCodeFormat = secretKey.getEncoded();  
45         SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
46         //创建密码器             
47         Cipher cipher = Cipher.getInstance("AES");
48         //初始化
49         cipher.init(Cipher.DECRYPT_MODE, key);
50         //Base64转码
51         byte[] encrypted1 = Base64.decode(content);
52         //解密
53         byte[] result = cipher.doFinal(encrypted1);
54         //二进制转为字符串
55         return new String(result, "utf-8");
56     } catch (NoSuchAlgorithmException e) {  
57         e.printStackTrace();  
58     } catch (NoSuchPaddingException e) {  
59         e.printStackTrace();  
60     } catch (InvalidKeyException e) {  
61         e.printStackTrace();  
62     } catch (IllegalBlockSizeException e) {  
63         e.printStackTrace();  
64     } catch (BadPaddingException e) {  
65         e.printStackTrace();  
66     }  
67     return null;  
68 }

 加密解密时密码器的输入输出都为2进制数组,这里我们用Base64在加解密的中间过程中进行了转码,所以可以以字符串形式展示加密后的密文,也可以使用下面的方法将二进制数组转换为16进制的字符串来表示,同样起到转换的作用

 1 //将二进制数组转化为16进制字符串
 2 public static String parseByte2HexStr(byte buf[]) {  
 3     StringBuffer sb = new StringBuffer();  
 4     for (int i = 0; i < buf.length; i++) {  
 5         String hex = Integer.toHexString(buf[i] & 0xFF);  
 6         if (hex.length() == 1) {  
 7             hex = '0' + hex;  
 8         }  
 9         sb.append(hex.toUpperCase());  
10     }  
11     return sb.toString();  
12 }
13 //将16进制字符串转化为二进制数组
14 public static byte[] parseHexStr2Byte(String hexStr) {  
15     if (hexStr.length() < 1)  
16         return new byte[0];  
17     byte[] result = new byte[hexStr.length()/2];  
18     for (int i = 0;i< hexStr.length()/2; i++) {  
19         int high = Integer.parseInt(hexStr.substring(i*2, i*2+1), 16);  
20         int low = Integer.parseInt(hexStr.substring(i*2+1, i*2+2), 16);  
21         result[i] = (byte) (high * 16 + low);  
22     }  
23     return result;  
24 }

 源码下载

原文地址:https://www.cnblogs.com/Aoobruce/p/8243325.html