用Java生成的数据解密PHP中的AES-128

时间:2016-10-04 15:32:00

标签: java php encryption aes mcrypt

在Stackoverflow和其他网站上使用了很多不同的例子,我设法创建了一个工作的Java类,用于使用AES-128加密和解密字符串。我需要在PHP中对这些相同的字符串进行解密和加密以允许双向通信,但是使用PHP的mcrypt我会得到混乱和破碎的字符串,这些字符串并不接近我想要实现的目标。

这是Java源代码(包含在函数中):

        MessageDigest digest = MessageDigest.getInstance("SHA-256");
        byte[] keyBytes = password.getBytes("UTF-8");
        digest.update(keyBytes);
        keyBytes = Arrays.copyOf(digest.digest(), 16);

        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
        byte[] iv = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,};
        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);

        cipher.init(Cipher.DECRYPT_MODE, keySpec, ivParameterSpec);
        byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedText));

        return new String(decryptedBytes);

例如,这会使用密钥/密码dyHuhcYI3JIQ4BssSyJ3bjE/sQCOH+fWq2EujW579BU=返回J@RMZyv7~Dyd,并且可以使用相同的密钥解密为Dit bericht is versleuteld!

在PHP中,我使用的代码少得多,而且我不确定哪里出错了。我使用V1gbTVCCbQK7cknbbir5Gg==作为解密密钥的密钥,这是上面keyBytes变量的base64编码版本。

$decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, base64_decode("V1gbTVCCbQK7cknbbir5Gg=="), base64_decode("vdyHuhcYI3JIQ4BssSyJ3bjE/sQCOH+fWq2EujW579BU="), MCRYPT_MODE_CBC, "0000000000000000");
var_dump($decrypted);

这会产生一些破碎的字符串,我还不确定如何解决这个问题。我确信我的PHP实现有些问题,因为我可以用Java成功加密和解密它。

1 个答案:

答案 0 :(得分:0)

事实证明我使用的IV并不完全正确。在尝试this回答中的问题后,我发现使用以下代码我可以成功解密我的邮件:

function hexToStr($hex)
{
    $string = '';
    for ($i = 0; $i < strlen($hex) - 1; $i += 2) {
        $string .= chr(hexdec($hex[$i] . $hex[$i + 1]));
    }
    return $string;
}
$decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, base64_decode($key), base64_decode($encrypted), MCRYPT_MODE_CBC, hexToStr('00000000000000000000000000000000'));

请注意,IV现在正在使用该函数而不是值&#34; 0000000000000000&#34;。