【发布时间】:2019-07-15 12:27:13
【问题描述】:
我正在运行 PHP 7.2.8。根据openssl_get_cipher_methodschacha20-poly1305 是支持的算法:
echo in_array('chacha20-poly1305', openssl_get_cipher_methods()) ? 'yes' : 'no';
输出“是”。
所以我尝试使用chacha20-poly1305:
$plaintext = 'zzzzzz';
$key = str_repeat('k', 32);
$nonce = str_repeat('n', 12);
$aad = '';
$r = openssl_encrypt(
$plaintext,
'chacha20-poly1305',
$key,
OPENSSL_RAW_DATA,
$nonce,
$newtag,
$aad
);
echo bin2hex($r);
输出一个 PHP 警告:
警告:openssl_encrypt():无法为不支持 AEAD 的密码提供经过身份验证的标签
$r 是 f4854428b8a8。
我能够为r 和chacha20 获得相同的输出(即通过这样做没有poly1305):
$r = openssl_encrypt(
$plaintext,
'chacha20',
$key,
OPENSSL_RAW_DATA,
"\1\0\0\0" . $nonce
);
输出相同的事实意味着 Poly1305 身份验证代码既没有附加也没有附加到密文中。
我的问题是...如何在 PHP 中使用 OpenSSL 获取 Poly1305 身份验证代码?
另外,我知道 libsodium 提供 chacha20-poly1305 支持,但我仍然对它应该如何与 OpenSSL 一起使用感到好奇。
【问题讨论】:
-
如果我没记错的话,ChaCha20/Poly1305 更像是 OpenSSL 在 TLS 中使用的内部密码。它不适用于
EVP_*接口、openssl enc或openssl dec。事实上,我不相信 OpenSSL 子命令(enc和dec)支持经过身份验证的加密模式,因为无法检索或指定它们。然而,自 OpenSSL 1.1.0 以来,情况可能发生了变化。 -
@jww -
enc和dec支持 aes-128-gcm 等,但我认为(以及 aes-192-gcm 和 aes-256-gcm)和 chacha20-poly1305是 OpenSSL 支持的唯一 AEAD 算法。而且 chacha20-poly1305 的行为似乎确实不同,所以你评论它只是内部的很可能是真的 -
"enc 和 dec 支持 aes-128-gcm" - 实际上,它不支持(或者过去不支持)。子命令接受密码是一个错误。请参阅 OpenSSL 邮件列表中的 v1.0.1g command line gcm error;和OpenSSL RT Issue 3354。很抱歉把头发分开。
-
平@mattcaswell。 Matt 是 OpenSSL 开发人员之一,他有时会在 Stack Overflow 上巡逻。他可能无需查看消息来源就可以准确地告诉您正在发生的事情。
-
@jww - PHP 的 OpenSSL 绑定确实支持 aes-128-gcm,pastebin.com/kbqX7mAq 证明了这一点。我在 PHP 7.2.8 上得到了没有错误的输出。只是 chacha20-poly1305 给出了该错误(至少在 aes-128-gcm、aes-256-gcm 和 chacha20-poly1305 中)
标签: php openssl cryptography php-openssl