AES-256-GCM 模式解密在 php 中失败

AES-256-GCM mode decryption fails in php

这是我的代码:

<?php
$secret="This is a secret message.";
$key="Secret key.";
$iv=openssl_random_pseudo_bytes(12);
$method="aes-256-gcm";

$encrypted=openssl_encrypt($secret,$method,$key,false,$iv);
$decrypted=openssl_decrypt($encrypted,$method,$key,false,$iv);

echo $encrypted;
echo "<br>";
echo $decrypted;
?>

我收到了加密的消息,但解密没有给出任何结果或错误消息。 相同的代码正在使用另一种方法,例如 aes-256-cbc。

在我的系统上测试他(PHP 5.3.10 在内部使用 return OpenSSL 1.0.1)returns 一个与明文(消息)长度相同的密文.

这意味着 GCM 加密不 return 身份验证标记,只是内部 CTR 模式加密。这可能是因为 PHP 包装器只是直接调用 OpenSSL 接口而不使用以下代码:

if(1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, tag))
    handleErrors();

在使用 GCM 的 OpenSSL EVP ("higher level") 加密的示例代码中找到。换句话说,标签需要单独检索。

单独处理标签确实有意义 - 它可以创建一个使用更少缓冲的更在线的实现 - 但这对你没有帮助。您可以在 IV 和密文上使用 AES-CBC 后跟 HMAC 来替换 GCM 模式。使用单独的密钥进行加密和身份验证标记会使该方案更加安全。


PS由于初始化不同,不能直接使用CTR模式解密再次取回明文