https://www.cnblogs.com/catalina-/p/6001831.html
加密代码
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 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; } |
测试结果,问题解决
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