Java端的AES加密 – 在PHP端解密并选择单个密钥

我正在使用AES,我想找到一个可以在Java端加密字符串的密钥,我在php端硬编码相同的密钥,如果字符串匹配则解密字符串我已经过身份validation。

以下是我在Java中的代码:

public class AESencrp { private static final String ALGO = "AES"; private static final byte[] keyValue = new byte[] { 'T', 'h', 'e', 'B', 'e', 's', 't', 'S', 'e', 'c', 'r','e', 't', 'K', 'e', 'y' }; public static String encrypt(String Data) throws Exception { Key key = generateKey(); Cipher c = Cipher.getInstance(ALGO); c.init(Cipher.ENCRYPT_MODE, key); byte[] encVal = c.doFinal(Data.getBytes()); String encryptedValue = new BASE64Encoder().encode(encVal); return encryptedValue; } public static String decrypt(String encryptedData) throws Exception { Key key = generateKey(); Cipher c = Cipher.getInstance(ALGO); c.init(Cipher.DECRYPT_MODE, key); byte[] decordedValue = new BASE64Decoder().decodeBuffer(encryptedData); byte[] decValue = c.doFinal(decordedValue); String decryptedValue = new String(decValue); return decryptedValue; } private static Key generateKey() throws Exception { Key key = new SecretKeySpec(keyValue, ALGO); return key; } } 

这是我在PHP中使用的函数:

 function fnDecrypt() { // echo $_POST['key']; $sValue = $_POST['key']; $sSecretKey = "TheBestSecretKey"; return rtrim( mcrypt_decrypt( MCRYPT_RIJNDAEL_256, $sSecretKey, base64_decode($sValue), MCRYPT_MODE_CBC, mcrypt_create_iv( mcrypt_get_iv_size( MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC ), MCRYPT_RAND ) ), "\0" ); } 

然而,似乎我总是在php端获得不同的解密文本,我觉得问题是关键,而我正在努力编码,这种行为不应该发生,任何提示?

似乎有一些事情你做错了,我会按顺序翻看这些:

在Java中创建Cipher实例时,始终指定"Algorithm/Mode/Padding" 。 否则你永远不知道将使用哪种模式和填充,如果你想在不同平台和编程语言之间传递加密数据,这尤其成问题,因为它们可能有不同的默认值。 (例如,Java的默认填充是PKCS1Padding ,而PHP的mcrypt_decrypt()需要ZeroBytePadding
所以初始化ALGO

 /* ZeroBytePadding should better not be used in practice */ private static final String ALGO = "AES/CBC/ZeroBytePadding"; 

正如Roland Jansen已经提到的那样,Java AES是128位版本。 所以在PHP中使用:

 MCRYPT_RIJNDAEL_128 

第三,您必须始终为每个加密指定不同的随机IV (不得保密)。 然后,您必须使用相同的IV进行解密。 因此,您还必须在java中生成一个IV ,然后将其传递给PHP并在那里用于解密。

 byte[] iv = new byte[16]; // must be 16 bytes for AES-128 new SecureRandom().nextBytes(iv); // generate random bytes IvParameterSpec ivSpec = new IvParameterSpec(iv); /* create instance of Cipher and keys */ cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec); 

截至目前,您还在PHP中生成随机IV ,这显然不会导致所需的明文。 所以在php中进行以下解密:

  $key = "{insert Java encryption key here}"; $iv; = "{insert Java encryption IV here}"; mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $ciphertext, MCRYPT_MODE_CBC, $iv); 

如果在这些修复之后它仍然不起作用,则问题可能是密文或键/ IV字符串的编码。 尝试确保将完全相同的数据传递给从Java接收到cipher.doFinal PHP。

我希望,我可以帮助你。

这个链接http://www.androidsnippets.com/encrypt-decrypt-between-android-and-php有一个教程可以帮助你。 如果你想改变SecretKey。