您可以在
padAndMcrypt()函数中看到,给定的$
value是使用PHP的
serialize()function序列化的。您可以用Java
重新实现该
unserialize()功能,或者如果您始终使用PHP加密字符串,则可以自己拆分字节数组。
int firstQuoteIndex = 0;while(decValue[firstQuoteIndex] != (byte)'"') firstQuoteIndex++;return new String(Arrays.copyOfRange(decValue, firstQuoteIndex + 1, decValue.length-2));
完整代码:
public static String decrypt(byte[] keyValue, String ivValue, String encryptedData) throws Exception { Key key = new SecretKeySpec(keyValue, "AES"); byte[] iv = base64.depre(ivValue.getBytes("UTF-8"), base64.DEFAULT); byte[] depredValue = base64.depre(encryptedData.getBytes("UTF-8"), base64.DEFAULT); Cipher c = Cipher.getInstance("AES/CBC/PKCS7Padding"); // or PKCS5Padding c.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv)); byte[] decValue = c.doFinal(depredValue); int firstQuoteIndex = 0; while(decValue[firstQuoteIndex] != (byte)'"') firstQuoteIndex++; return new String(Arrays.copyOfRange(decValue, firstQuoteIndex + 1, decValue.length-2));}验证MAC始终是一个好主意,因为它可以防止某些攻击,例如padding oracle攻击。这也是检测密文的一般修改的一种非常好的方法。
具有MAC验证的完整代码:
public static String decrypt(byte[] keyValue, String ivValue, String encryptedData, String macValue) throws Exception { Key key = new SecretKeySpec(keyValue, "AES"); byte[] iv = base64.depre(ivValue.getBytes("UTF-8"), base64.DEFAULT); byte[] depredValue = base64.depre(encryptedData.getBytes("UTF-8"), base64.DEFAULT); SecretKeySpec macKey = new SecretKeySpec(keyValue, "HmacSHA256"); Mac hmacSha256 = Mac.getInstance("HmacSHA256"); hmacSha256.init(macKey); hmacSha256.update(ivValue.getBytes("UTF-8")); byte[] calcMac = hmacSha256.doFinal(encryptedData.getBytes("UTF-8")); byte[] mac = Hex.depreHex(macValue.toCharArray()); if (!secureEquals(calcMac, mac)) return null; // or throw exception Cipher c = Cipher.getInstance("AES/CBC/PKCS7Padding"); // or PKCS5Padding c.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv)); byte[] decValue = c.doFinal(depredValue); int firstQuoteIndex = 0; while(decValue[firstQuoteIndex] != (byte)'"') firstQuoteIndex++; return new String(Arrays.copyOfRange(decValue, firstQuoteIndex + 1, decValue.length-2));}public static boolean secureEquals(final byte[] known, final byte[] user) { int knownLen = known.length; int userLen = user.length; int result = knownLen ^ userLen; for (int i = 0; i < knownLen; i++) { result |= known[i] ^ user[i % userLen]; } return result == 0;}


