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。
- 在AES解密时,给定Final Block未正确填充
- 如何解密从Mifare Desfire EV1发送的第一条消息
- AES / CBC / PKCS5Padding与AES / CBC / PKCS7Padding具有256个密钥大小的性能java
- Java TLS 1.2服务器:AES-GCM解密
- Java使用AES 256和128对称密钥加密
- javax.crypto.IllegalBlockSizeException:解密时最后一个块不完整 – 解密加密的AES字符串
- java aes 256 java.security.InvalidKeyException:安装策略后出现非法密钥大小
- PHP Java AES CBC加密不同的结果
- 在Java中加密和在C#中解密为AES 256位