javax.crypto.BadPaddingException: Given final block not properly padded

在項目中運用到了Java的AES加密,本地Windows調試一切正常,部署到Linux服務器後一直報空指針異常。java

通過一番調試,找到真正緣由:javax.crypto.BadPaddingException: Given final block not properly paddedlinux

 1 package com.daredo.utils;
 2 
 3 import javax.crypto.Cipher;
 4 import javax.crypto.KeyGenerator;
 5 import javax.crypto.SecretKey;
 6 import javax.crypto.spec.SecretKeySpec;
 7 import java.security.SecureRandom;
 8 
 9 /**
10  * Created by IntelliJ IDEA
11  * Author: d-arlin@qq.com
12  * Date: 2018/3/14
13  * Time: 15:38
14  */
15 public class SecurityUtils {
16 
17     /**
18      * 編碼格式
19      */
20     private static String ENCODING = "UTF-8";
21     /**
22      * 加密算法
23      */
24     public static final String KEY_ALGORITHM = "AES";
25 
26     /**
27      * 加密
28      *
29      * @param content 待加密內容
30      * @param key     加密的密鑰
31      * @return
32      */
33     public static String encrypt(String content, String key) {
34         try {
35             KeyGenerator kgen = KeyGenerator.getInstance(KEY_ALGORITHM);
36             kgen.init(128, new SecureRandom(key.getBytes(ENCODING)));
37             SecretKey secretKey = kgen.generateKey();
38             byte[] enCodeFormat = secretKey.getEncoded();
39             SecretKeySpec secretKeySpec = new SecretKeySpec(enCodeFormat, KEY_ALGORITHM);
40             Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
41             byte[] byteContent = content.getBytes(ENCODING);
42             cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
43             byte[] byteRresult = cipher.doFinal(byteContent);
44             StringBuffer sb = new StringBuffer();
45             for (int i = 0; i < byteRresult.length; i++) {
46                 String hex = Integer.toHexString(byteRresult[i] & 0xFF);
47                 if (hex.length() == 1) hex = '0' + hex;
48                 sb.append(hex.toUpperCase());
49             }
50             return sb.toString();
51         } catch (Exception e) {
52             e.toString();
53         }
54         return null;
55     }
56 
57     /**
58      * 解密
59      *
60      * @param content 待解密內容
61      * @param key     解密的密鑰
62      * @return
63      */
64     public static String decrypt(String content, String key) {
65         if (content.length() < 1) return null;
66         byte[] byteRresult = new byte[content.length() / 2];
67         for (int i = 0; i < content.length() / 2; i++) {
68             int high = Integer.parseInt(content.substring(i * 2, i * 2 + 1), 16);
69             int low = Integer.parseInt(content.substring(i * 2 + 1, i * 2 + 2), 16);
70             byteRresult[i] = (byte) (high * 16 + low);
71         }
72         try {
73             KeyGenerator kgen = KeyGenerator.getInstance(KEY_ALGORITHM);
74             kgen.init(128, new SecureRandom(key.getBytes(ENCODING)));
75             SecretKey secretKey = kgen.generateKey();
76             byte[] enCodeFormat = secretKey.getEncoded();
77             SecretKeySpec secretKeySpec = new SecretKeySpec(enCodeFormat, KEY_ALGORITHM);
78             Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
79             cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
80             byte[] result = cipher.doFinal(byteRresult);
81             return new String(result, ENCODING);
82         } catch (Exception e) {
83             e.toString();
84         }
85         return null;
86     }
87 
88 }

 

那麼爲何在Windows正常,在Linux就出現異常呢?算法

緣由分析
SecureRandom 實現徹底隨操做系統自己的內部狀態,除非調用方在調用 getInstance 方法以後又調用了 setSeed 方法;windows

該實如今 windows 上每次生成的 key 都相同,可是在 solaris 或部分 linux 系統上則不一樣。服務器

解決方法app

 1 package com.daredo.utils;
 2 
 3 import javax.crypto.Cipher;
 4 import javax.crypto.KeyGenerator;
 5 import javax.crypto.SecretKey;
 6 import javax.crypto.spec.SecretKeySpec;
 7 import java.security.SecureRandom;
 8 
 9 /**
10  * Created by IntelliJ IDEA
11  * Author: d-arlin@qq.com
12  * Date: 2018/3/14
13  * Time: 15:38
14  */
15 public class SecurityUtils {
16 
17     /**
18      * 編碼格式
19      */
20     private static final String ENCODING = "UTF-8";
21     /**
22      * 加密算法
23      */
24     public static final String KEY_ALGORITHM = "AES";
25     /**
26      * 簽名算法
27      */
28     public static final String SIGN_ALGORITHMS = "SHA1PRNG";
29 
30     /**
31      * 加密
32      *
33      * @param content 待加密內容
34      * @param key     加密的密鑰
35      * @return
36      */
37     public static String encrypt(String content, String key) {
38         try {
39             KeyGenerator kgen = KeyGenerator.getInstance(KEY_ALGORITHM);
40             SecureRandom random = SecureRandom.getInstance(SIGN_ALGORITHMS);
41             random.setSeed(key.getBytes(ENCODING));
42             kgen.init(128, random);
43             SecretKey secretKey = kgen.generateKey();
44             byte[] enCodeFormat = secretKey.getEncoded();
45             SecretKeySpec secretKeySpec = new SecretKeySpec(enCodeFormat, KEY_ALGORITHM);
46             Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
47             byte[] byteContent = content.getBytes(ENCODING);
48             cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
49             byte[] byteRresult = cipher.doFinal(byteContent);
50             StringBuffer sb = new StringBuffer();
51             for (int i = 0; i < byteRresult.length; i++) {
52                 String hex = Integer.toHexString(byteRresult[i] & 0xFF);
53                 if (hex.length() == 1) hex = '0' + hex;
54                 sb.append(hex.toUpperCase());
55             }
56             return sb.toString();
57         } catch (Exception e) {
58             e.toString();
59         }
60         return null;
61     }
62 
63     /**
64      * 解密
65      *
66      * @param content 待解密內容
67      * @param key     解密的密鑰
68      * @return
69      */
70     public static String decrypt(String content, String key) {
71         if (content.length() < 1) return null;
72         byte[] byteRresult = new byte[content.length() / 2];
73         for (int i = 0; i < content.length() / 2; i++) {
74             int high = Integer.parseInt(content.substring(i * 2, i * 2 + 1), 16);
75             int low = Integer.parseInt(content.substring(i * 2 + 1, i * 2 + 2), 16);
76             byteRresult[i] = (byte) (high * 16 + low);
77         }
78         try {
79             KeyGenerator kgen = KeyGenerator.getInstance(KEY_ALGORITHM);
80             SecureRandom random = SecureRandom.getInstance(SIGN_ALGORITHMS);
81             random.setSeed(key.getBytes(ENCODING));
82             kgen.init(128, random);
83             SecretKey secretKey = kgen.generateKey();
84             byte[] enCodeFormat = secretKey.getEncoded();
85             SecretKeySpec secretKeySpec = new SecretKeySpec(enCodeFormat, KEY_ALGORITHM);
86             Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
87             cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
88             byte[] result = cipher.doFinal(byteRresult);
89             return new String(result, ENCODING);
90         } catch (Exception e) {
91             e.toString();
92         }
93         return null;
94     }
95 
96 }

改動的地方如代碼中已標紅。dom

相關文章
相關標籤/搜索