1、PHP 8.4 新特性 - Sodium:支持 AEGIS-128L 和 AEGIS-256
PHP 8.4 引入了对 AEGIS-128L 和 AEGIS-256 的支持,这两种加密算法是 Sodium 扩展(即 libsodium
)中的新功能。它们是高效的 AEAD(Authenticated Encryption with Associated Data)加密模式,提供了强大的性能和安全性,适合对敏感数据进行快速加密和验证。
AEGIS 是一种基于 AES 的认证加密算法家族,其速度比 AES-GCM 更快。PHP 8.4 中的 Sodium 扩展在使用 libsodium 1.0.19 或更高版本编译时支持 AEGIS-128L 和 AEGIS256 加密算法。
PHP 8.4 中的 Sodium 扩展通过 PHP 函数支持 AEGIS-128L 和 AEGIS256,这些函数遵循 _keygen
、_encrypt
和 _decrypt
的模式,与现有的 aes256gcm、chacha20poly1305、chacha20poly1305_ietf 和 xchacha20poly1305 加密算法的模式一致。这些算法均为带附加数据认证加密(AEAD)算法。
1、新函数和 PHP 常量
PHP 8.4 中的 Sodium 扩展为 AEGIS-128L 和 AEGIS-256 AEAD 算法新增了 6 个 PHP 函数和 4 个 PHP 常量。
1.1、AEGIS-128L 函数和常量
AEGIS-128L 是一种 AEAD 算法,它使用 128 位密钥和 128 位随机数(nonce),可以加密/解密长度小于 2*64 位的数据。
函数
-
sodium_crypto_aead_aegis128l_keygen
函数:为 AEGIS-128L 生成并返回指定长度(
SODIUM_CRYPTO_AEAD_AEGIS128L_KEYBYTES
)的加密安全随机密钥。 -
sodium_crypto_aead_aegis128l_encrypt
函数:使用 AEGIS-128L 算法对明文数据进行加密并认证。
-
sodium_crypto_aead_aegis128l_decrypt
函数:使用 AEGIS-128L 算法对加密数据进行验证后解密。
函数原型如下:
sodium_crypto_aead_aegis128l_keygen
/**
* 生成一个随机的 AEGIS-128L 密钥
*
* @return string
*/
function sodium_crypto_aead_aegis128l_keygen(): string {
}
sodium_crypto_aead_aegis128l_encrypt
/**
* 使用 AEGIS-128L 加密后进行认证
*
* @param string $message 要加密的明文消息
* @param string $additional_data 额外的认证数据。这些数据用于验证附加到密文后的认证标签,但不会被加密或存储在密文中
* @param string $nonce 一个必须仅对每条消息使用一次的数字。长度为16字节
* @param string $key 加密密钥(128位)
*
* @return string
*/
function sodium_crypto_aead_aegis128l_encrypt(string $message, string $additional_data, string $nonce, string $key): string {
}
sodium_crypto_aead_aegis128l_decrypt
/**
* 验证并解密一条由 sodium_crypto_aead_aegis128l_encrypt() 函数加密的消息
*
* @param string $message 由 sodium_crypto_aead_aegis128l_encrypt() 函数创建的加密消息
* @param string $additional_data 额外的认证数据。这些数据用于验证附加到密文后的认证标签,但不会被加密或存储在密文中。这必须与加密明文消息时传递的值相同
* @param string $nonce 一个必须仅对每条消息使用一次的数字。长度为16字节。这必须与加密明文消息时传递的nonce值相同
* @param string $key 加密密钥(128位)
*
* @return string
*/
function sodium_crypto_aead_aegis128l_decrypt(string $message, string $additional_data, string $nonce, string $key): string {
}
常量
-
SODIUM_CRYPTO_AEAD_AEGIS128L_KEYBYTES
常量:指定 AEGIS-128L 算法使用的密钥长度(字节数),值为 16。 -
SODIUM_CRYPTO_AEAD_AEGIS128L_NPUBBYTES
常量:指定 AEGIS-128L 算法使用的随机数(nonce)长度(字节数),值为 16。 -
SODIUM_CRYPTO_AEAD_AEGIS128L_NSECBYTES
常量:值为 0。 -
SODIUM_CRYPTO_AEAD_AEGIS128L_ABYTES
常量:值为 32。
1.2、AEGIS-256 函数和常量
函数
-
sodium_crypto_aead_aegis256_keygen
函数:为 AEGIS-256 生成并返回指定长度(
SODIUM_CRYPTO_AEAD_AEGIS256_KEYBYTES
)的加密安全随机密钥。 -
sodium_crypto_aead_aegis256_encrypt
函数:使用 AEGIS-256 算法对明文数据进行加密并认证。
-
sodium_crypto_aead_aegis256_decrypt
函数:使用 AEGIS-256 算法对加密数据进行验证后解密。
sodium_crypto_aead_aegis256_keygen
/**
* 生成一个随机的 AEGIS-256 密钥
*
* @return string
*/
function sodium_crypto_aead_aegis256_keygen(): string {
}
sodium_crypto_aead_aegis256_encrypt
/**
* 使用 AEGIS-256 加密并认证
*
* @param string $message 要加密的明文消息
* @param string $additional_data 额外的认证数据。这些数据用于验证附加到密文后的认证标签,但不会被加密或存储在密文中
* @param string $nonce 一个必须仅对每条消息使用一次的数字。长度为32字节
* @param string $key 加密密钥(256位)
*
* @return string
*/
function sodium_crypto_aead_aegis256_encrypt(string $message, string $additional_data, string $nonce, string $key): string {
}
sodium_crypto_aead_aegis256_decrypt
/**
* 验证并解密一条由 sodium_crypto_aead_aegis256_encrypt() 函数加密的消息
*
* @param string $ciphertext 由 sodium_crypto_aead_aegis256_encrypt() 函数创建的加密消息
* @param string $additional_data 额外的认证数据。这些数据用于验证附加到密文后的认证标签,但不会被加密或存储在密文中。这必须与加密明文消息时传递的值相同
* @param string $nonce 一个必须仅对每条消息使用一次的数字。长度为32字节。这必须与加密明文消息时传递的nonce值相同
* @param string $key 加密密钥(256位)
*
* @return string|false
*/
function sodium_crypto_aead_aegis256_decrypt(string $ciphertext, string $additional_data, string $nonce, string $key): string|false {
}
常量
-
SODIUM_CRYPTO_AEAD_AEGIS256_KEYBYTES
常量:指定 AEGIS-256 算法使用的密钥长度(字节数),值为 32。 -
SODIUM_CRYPTO_AEAD_AEGIS256_NPUBBYTES
常量:指定 AEGIS-256 算法使用的随机数(nonce)长度(字节数),值为 32。 -
SODIUM_CRYPTO_AEAD_AEGIS256_NSECBYTES
常量:值为 0。 -
SODIUM_CRYPTO_AEAD_AEGIS256_ABYTES
常量:值为 32。
2、检查 AEGIS-128L 和 AEGIS-256 可用性
没有专门的函数类似于 sodium_crypto_aead_aes256gcm_is_available
来返回 AEGIS-128L 和 AEGIS-256 AEAD 算法是否可用。
注意:
新的函数和常量只有在满足所有要求时才会声明。**
这些要求包括 x86_64 或 aarch64 CPU、PHP 8.4 以及 Sodium 扩展必须编译有 libsodium 1.0.19 或更高版本。
**检查其中一个新函数的存在性可以作为这些算法可用性的检查:
if (function_exists('sodium_crypto_aead_aegis256_encrypt')) {
// AEGIS-128L 和 AEGIS-256 可用。
echo '可用';
} else {
// AEGIS-128L 和 AEGIS-256 不可用。
echo '不可用';
}
现在查看一个 libsodium
版本:
sodium support | enabled |
---|---|
libsodium headers version | 1.0.18 |
libsodium library version | 1.0.18 |
我的版本是 1.0.18
,因此这个代码会输出不可用
。要想使用这些函数,就必须要升级 libsodium
扩展到 1.0.19
或更高版本。
3、案例
sodium support | enabled |
---|---|
sodium compiled version | 2.0.22 |
libsodium headers version | 1.0.20 |
libsodium library version | 1.0.20 |
使用 AEGIS-128L 进行加密和解密
<?php
// 密钥 (必须是 16 字节,适合 AEGIS-128L)
$key = random_bytes(SODIUM_CRYPTO_AEAD_AEGIS128L_KEYBYTES);
// Nonce (随机数,必须是 16 字节)
$nonce = random_bytes(SODIUM_CRYPTO_AEAD_AEGIS128L_NPUBBYTES);
// 要加密的消息
$message = "这是需要加密的敏感数据。";
// 关联数据(可选,用于完整性校验,不会加密)
$associated_data = "元数据";
// 加密消息
$encrypted = sodium_crypto_aead_aegis128l_encrypt($message, $associated_data, $nonce, $key);
echo "加密后的数据: " . bin2hex($encrypted) . PHP_EOL;
// 解密消息
$decrypted = sodium_crypto_aead_aegis128l_decrypt($encrypted, $associated_data, $nonce, $key);
if ($decrypted === false) {
echo "解密失败,可能密钥或 nonce 不匹配。" . PHP_EOL;
} else {
echo "解密成功,消息为: " . $decrypted . PHP_EOL;
}
密钥和 Nonce:
- 密钥和 Nonce 的大小固定,分别为 16 字节。
- Nonce 必须唯一,以防止重复攻击。
关联数据:
- 关联数据是加密过程中不加密但需要认证的部分。
- 常用于存储元信息(如消息头、时间戳)。
加密与解密:
- 加密后返回的是加密数据。
- 解密时,如果关联数据或 Nonce 不匹配,会返回
false
。
AEGIS-256 的用法
如果需要更高安全性,使用 AEGIS-256
加密
<?php
// 密钥 (必须是 32 字节,适合 AEGIS-256)
$key = random_bytes(SODIUM_CRYPTO_AEAD_AEGIS256_KEYBYTES);
// Nonce (必须是 32 字节)
$nonce = random_bytes(SODIUM_CRYPTO_AEAD_AEGIS256_NPUBBYTES);
// 加密消息
$encrypted = sodium_crypto_aead_aegis256_encrypt($message, $associated_data, $nonce, $key);
// 解密消息
$decrypted = sodium_crypto_aead_aegis256_decrypt($encrypted, $associated_data, $nonce, $key);
适用场景
- 敏感数据加密:如支付信息、登录凭证等。
- 高性能需求:特别是对速度和认证有要求的应用场景。
- 替代传统 AEAD 算法:如 GCM 或 Chacha20-Poly1305。
4、向后兼容性影响
AEGIS-128L 和 AEGIS-256 算法作为新的函数和常量被添加到 PHP 8.4 的 Sodium 扩展中。
sodium_compat
项目提供了 Sodium 扩展的用户空间 PHP 多填充。该项目有一个开放的问题,旨在添加对 AEGIS-128L 和 AEGIS-256 的支持,尽管在这方面还没有进行任何工作