加密代码
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