加密代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | /\*\*解密 \* @param content 待解密内容 \* @param password 解密密钥 \* @return \*/public static byte\[\] decrypt(byte\[\] content, String password) { try { KeyGenerator kgen = KeyGenerator.getInstance("AES"); kgen.init(128, new SecureRandom(password.getBytes())); SecretKey secretKey = kgen.generateKey(); byte\[\] enCodeFormat = secretKey.getEncoded(); SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES"); Cipher cipher = Cipher.getInstance("AES");// 创建密码器 cipher.init(Cipher.DECRYPT\_MODE, key);// 初始化 byte\[\] result = cipher.doFinal(content); return result; // 加密 } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (NoSuchPaddingException e) { e.printStackTrace(); } catch (InvalidKeyException e) { e.printStackTrace(); } catch (IllegalBlockSizeException e) { e.printStackTrace(); } catch (BadPaddingException e) { e.printStackTrace(); } return null;} |
解密代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | /\*\*解密 \* @param content 待解密内容 \* @param password 解密密钥 \* @return \*/public static byte\[\] decrypt(byte\[\] content, String password) { try { KeyGenerator kgen = KeyGenerator.getInstance("AES"); kgen.init(128, new SecureRandom(password.getBytes())); SecretKey secretKey = kgen.generateKey(); byte\[\] enCodeFormat = secretKey.getEncoded(); SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES"); Cipher cipher = Cipher.getInstance("AES");// 创建密码器 cipher.init(Cipher.DECRYPT\_MODE, key);// 初始化 byte\[\] result = cipher.doFinal(content); return result; // 加密 } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (NoSuchPaddingException e) { e.printStackTrace(); } catch (InvalidKeyException e) { e.printStackTrace(); } catch (IllegalBlockSizeException e) { e.printStackTrace(); } catch (BadPaddingException e) { e.printStackTrace(); } return null;} |
解密代码
1 2 3 4 5 6 7 8 9 10 11 12 13 | String content = "test";String password = "12345678";//加密System.out.println("加密前:" + content);byte\[\] encryptResult = encrypt(content, password);try { String encryptResultStr = new String(encryptResult,"utf-8"); //解密 byte\[\] decryptResult = decrypt(encryptResultStr.getBytes("utf-8"),password); System.out.println("解密后:" + new String(decryptResult));} catch (UnsupportedEncodingException e) { e.printStackTrace();} |
偶尔会报错 抛出异常,
javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with padded cipher
原因 加密后的byte数组是不能强制转换成字符串的,换言之:字符串和byte数组在这种情况下不是互逆的;要避免这种情况,我们需要做一些修订,可以考虑将二进制数据转换成十六进制表示
解决方案
二进制转换成16进制
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | /\*\*将16进制转换为二进制 \* @param hexStr \* @return \*/public static byte\[\] parseHexStr2Byte(String hexStr) { if (hexStr.length() < 1) return null; byte\[\] result = new byte\[hexStr.length()/2\]; for (int i = 0;i< hexStr.length()/2; i++) { int high = Integer.parseInt(hexStr.substring(i\*2, i\*2+1), 16); int low = Integer.parseInt(hexStr.substring(i\*2+1, i\*2+2), 16); result\[i\] = (byte) (high \* 16 + low); } return result;} |
16进制转换为二进制
测试结果,问题解决
1 2 3 4 5 6 7 8 9 10 11 | String content = "test";String password = "12345678";//加密System.out.println("加密前:" + content);byte\[\] encryptResult = encrypt(content, password);String encryptResultStr = parseByte2HexStr(encryptResult);System.out.println("加密后:" + encryptResultStr);//解密byte\[\] decryptFrom = parseHexStr2Byte(encryptResultStr);byte\[\] decryptResult = decrypt(decryptFrom,password);System.out.println("解密后:" + new String(decryptResult)); |
测试结果如下:
加密前:test
加密后:73C58BAFE578C59366D8C995CD0B9D6D
解密后:test
加密后:73C58BAFE578C59366D8C995CD0B9D6D
解密后:test