【问题标题】:chacha20-poly1305 in PHP with OpenSSL带有 OpenSSL 的 PHP 中的 chacha20-poly1305
【发布时间】: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 的密码提供经过身份验证的标签

$rf4854428b8a8

我能够为rchacha20 获得相同的输出(即通过这样做没有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 encopenssl dec。事实上,我不相信 OpenSSL 子命令(encdec)支持经过身份验证的加密模式,因为无法检索或指定它们。然而,自 OpenSSL 1.1.0 以来,情况可能发生了变化。
  • @jww - encdec 支持 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


【解决方案1】:

OpenSSL 的问题仍未解决(2020 年 11 月),所以如果您需要使用 ChaCha20-Poly1305 使用 PHP 进行身份验证加密我推荐来自的库 可以实现的 Leigh (https://github.com/lt/PHP-AEAD-ChaCha20-Poly1305) 很容易。

auth-tag ($tag) 附加在密文后,需要先分开 开始解密。

请注意,因为我正在使用 OpenJDK 11 (Java) 测试相同的功能:这两个函数产生相同的密文但 不同 auth-tags,因此它们不能在跨平台中使用环境。

输出:

ChaCha20-Poly1305 encryption with leigh/aead-chacha20-poly1305
tag (16 bytes long, Base64): FK11WpqxhDuJytSgHN86tQ==
ciphertext (Base64):         1rXNtbeGF9KsMZXgPjszIeJ0Ze5ua+Uh5Aexu1ngaH4XoeldG71DwuDEAA==
decrypt: The quick brown fox jumps over the lazy dog

代码(安全警告:切勿在生产中使用静态密钥或随机数):

<?php
# make sure that you used Composer to get "leigh/aead-chacha20-poly1305"
require __DIR__ . '/vendor/autoload.php';

// ### never use static key & nonce in production, this is for testing only ###
$key = '12345678901234567890123456789012'; // 32 bytes
$nonce = '123456789012'; // 12 bytes
$plaintext = 'The quick brown fox jumps over the lazy dog';
$aad = '';

echo 'ChaCha20-Poly1305 encryption with leigh/aead-chacha20-poly1305' . PHP_EOL;
list($ciphertext, $tag) = \ChaCha20Poly1305\encrypt($key, $nonce, $aad, $plaintext);
echo 'tag (16 bytes long, Base64): ' . base64_encode($tag) . PHP_EOL;
echo 'ciphertext (Base64):         ' . base64_encode($ciphertext) . PHP_EOL;
$decrypt = \ChaCha20Poly1305\decrypt($key, $nonce, $aad, $ciphertext, $tag);
echo 'decrypt: ' . $decrypt . PHP_EOL;
?>

【讨论】:

    猜你喜欢
    • 2015-09-30
    • 1970-01-01
    • 2018-12-03
    • 1970-01-01
    • 2018-06-02
    • 2021-08-10
    • 2020-07-06
    • 2012-11-13
    • 1970-01-01
    相关资源
    最近更新 更多