在 PHP 中使用 OpenSSL 的 chacha20-poly1305

问题描述 投票:0回答:2

我运行的是 PHP 7.2.8。根据

openssl_get_cipher_methods
chacha20-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 一起使用。

php openssl cryptography php-openssl
2个回答
0
投票

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

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

请注意,我正在使用 OpenJDK 11 (Java) 测试相同的功能:两个函数都会生成相同的密文,但不同的身份验证标签,因此它们在跨平台环境中不可用。

输出:

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;
?>

0
投票

PHP 8.2 添加了对 chacha20-poly1305 的 AEAD 支持

我使用以下代码对其进行了测试,该代码与问题中显示的代码相同,只是它还打印了 AEAD 标签。

$plaintext = 'zzzzzz';
$key = str_repeat('k', 32);
$nonce = str_repeat('n', 12);
$aad = '';

$r = openssl_encrypt($plaintext, 'chacha20-poly1305', $key, OPENSSL_RAW_DATA, $nonce, $tag, $aad);

echo bin2hex($r), "\n", bin2hex($tag), "\n";

我得到的输出如下。

$ php test_chacha20.php                                                                                     
f4854428b8a8
0a0f1fab235b365765364a61e1bb68ff

没有打印任何警告。

© www.soinside.com 2019 - 2024. All rights reserved.