编程

PHP 8.4 预览: Sodium: AEGIS-128L 和 AEGIS256 支持

657 2024-01-03 22:57:00

PHP 8.4 是 PHP 的下一个主版本,离正式发布还有一些时日,但其中有些特性已经通过 RFC 投票并实现了。对那些已实现的新特性、更改及弃用等,本站将提前进行分享,供大家预览。

AEGIS 是基于 AES 的认证加密算法家族,其速度明显快于 AES-GCM。如果扩展是使用 libsodium 1.0.19 或更高版本编译的,则 PHP 8.4 中的 Sodium 扩展支持 AEGIS-128LAEGIS-256 加密算法。

PHP 8.4 Sodium 扩展支持 AEGIS-128LAEGIS256,使用的 PHP 函数遵循模式 _keygen_encrypt_decrypt,遵循的模式与现有的aes256gcmchacha20poly1305chacha20 poly1305_ietfxchacha20 poly1305 加密算法相同。所有这些都是附加数据身份验证加密(Authenticated Encryption with Additional Data, 即 AEAD)算法。

PHP Sodium 扩展的 AEGIS 加密
PHP 8.4中的 Sodium 扩展现在支持 AEGIS-128LAEGIS-256 身份验证加密密码。它们明显快于 AES-GCMCHACHA20-POLY1305。本文对它们进行了基准测试,并解释了如何在PHP上使用 AEGIS-128LAEGIS256 安全地加密和解密数据。 

新函数及 PHP 常量

PHP 8.4 中的 Sodium 扩展为 AEGIS-128LAEGIS-256 AEAD 算法添加了 6 个新的 PHP 函数及 4 个新的 PHP 常量,

AEGIS-128L 函数和常量

AEGIS-128L 是一个 AEAD 算法,接收一个 128 位的密钥和一个 128 位的 nonce 值,可以加密/解密小于 2*64 位的数据。

  • SODIUM_CRYPTO_AEAD_AEGIS128L_KEYBYTES 常量:AEGIS-128L 算法使用的密钥的字节数。值为 16
  • SODIUM_CRYPTO_AEAD_AEGIS128L_NPUBBYTES 常量:AEGIS-128L 算法使用的 nonce 值的字节数。 值为 16
  • 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 函数摘要

/**  
 * Generate a random AEGIS-128L key
 * @return string  
 */
function sodium_crypto_aead_aegis128l_keygen(): string {  
}

sodium_crypto_aead_aegis128l_encrypt 函数摘要

/**  
 * Encrypt then authenticate with AEGIS-128L.
 * @param string $message The plain-text message to encrypt.  
 * @param string $additional_data Additional, authenticated data. This is used in the verification of the authentication tag appended to the ciphertext, but it is not encrypted or stored in the ciphertext. 
 * @param string $nonce A number that must be only used once, per message. 16 bytes long.  
 * @param string $key Encryption key (128-bit).  
 * @return string Encrypted cipher-text  
 */
function sodium_crypto_aead_aegis128l_encrypt(string $message, string $additional_data, string $nonce, string $key): string {
}

sodium_crypto_aead_aegis128l_decrypt 函数摘要

/**  
 * Verify and then decrypt a message with AEGIS-128L.
 * @param string $message Encrypted message created by sodium_crypto_aead_aegis128l_encrypt() function.  
 * @param string $additional_data Additional, authenticated data. This is used in the verification of the authentication tag appended to the ciphertext, but it is not encrypted or stored in the ciphertext. This must be the same value passed when encrypting the plain-text message. 
 * @param string $nonce A number that must be only used once, per message. 16 bytes long. This must be the same nonce value passed when encrypting the plain-text message.
 * @param string $key Encryption key (128-bit).  
 * @return string Encrypted cipher-text
 */
function sodium_crypto_aead_aegis128l_decrypt(string $message, string $additional_data, string $nonce, string $key): string {}

AEGIS-256 函数和常量

  • SODIUM_CRYPTO_AEAD_AEGIS256_KEYBYTES 常量: AEGIS-256 算法使用的密钥值的字节数。值为 32
  • SODIUM_CRYPTO_AEAD_AEGIS256_NPUBBYTES 常量: AEGIS-256 算法使用的 nonce 值的字节数。 值为 32
  • sodium_crypto_aead_aegis256_keygen 函数: 生成并返回 AEGIS-256 所需长度 (SODIUM_CRYPTO_AEAD_AEGIS128L256_KEYBYTES)的加密安全随机数
  • sodium_crypto_aead_aegis256_encrypt 函数: 使用 AEGIS-256 加密并认证普通文本数据
  • sodium_crypto_aead_aegis256_decrypt 函数: 验证并解密 AEGIS-256 信息

sodium_crypto_aead_aegis256_keygen 函数摘要

/**  
 * Generate a random AEGIS-256 key
 * @return string  
 */
function sodium_crypto_aead_aegis256_keygen(): string {  
}

sodium_crypto_aead_aegis256_encrypt 函数摘要

/**  
 * Encrypt and then authenticate with AEGIS-256.
 * @param string $message The plain-text message to encrypt.  
 * @param string $additional_data Additional, authenticated data. This is used in the verification of the authentication tag appended to the ciphertext, but it is not encrypted or stored in the ciphertext. 
 * @param string $nonce A number that must be only used once, per message. 32 bytes long.  
 * @param string $key Encryption key (256-bit).  
 * @return string Encrypted cipher-text  
 */
function sodium_crypto_aead_aegis256_encrypt(string $message, string $additional_data, string $nonce, string $key): string {
}

sodium_crypto_aead_aegis256_decrypt 函数摘要

/**  
 * Verify and then decrypt a message with AEGIS-256.
 * @param string $message Encrypted message created by sodium_crypto_aead_aegis256_encrypt() function.  
 * @param string $additional_data Additional, authenticated data. This is used in the verification of the authentication tag appended to the ciphertext, but it is not encrypted or stored in the ciphertext. This must be the same value passed when encrypting the plain-text message. 
 * @param string $nonce A number that must be only used once, per message. 32 bytes long. This must be the same nonce value passed when encrypting the plain-text message.
 * @param string $key Encryption key (256-bit).  
 * @return string Encrypted cipher-text
 */
function function sodium_crypto_aead_aegis256_decrypt(string $ciphertext, string $additional_data, string $nonce, string $key): string|false

检测 AEGIS-128LAEGIS-256 可用性

没有类似于 sodium_crypto_aead_aes256gcm_is_available 的函数,用来返回 AEGIS-128L and AEGIS-256 AEAD 算法是否可用。

不过,新函数和常量只有在满足可用要求时会被声明。这些要求包括 x86_64aarch64 CPU、PHP 8.4 以及使用 libsodium 1.0.19 以上版本编译的 Sodium 扩展。检测这些函数是否可用可以用来检测这些算法是否可用:

 

function_exists('sodium_crypto_aead_aegis256_encrypt') {
    // AEGIS-128L available.
}

AEGIS-128LAEGIS-256 用例

See AEGIS Encryption with PHP Sodium Extension for detailed information and benchmarks on these two AEAD algorithms.

以下是两个新的加密算法的快速示例。

AEGIS-128L

// generate a random key of sufficient length (16 bytes)
// This value must not be public.
$key = sodium_crypto_aead_aegis128l_keygen();

// Generate random nonce value of SODIUM_CRYPTO_AEAD_AEGIS128L_NPUBBYTES length (16 bytes).
// This value should be stored along the encrypted text, but is not required to be private
$nonce = random_bytes(SODIUM_CRYPTO_AEAD_AEGIS128L_NPUBBYTES);

// Additional data. This can be a user ID, email address, or empty.
$additional_data = '';

// Message to encrypt
$message = 'Hello';

// Encrypt
$ciphertext = sodium_crypto_aead_aegis128l_encrypt($message, $additional_data, $nonce, $key);

// Decrypt
$decryptedMessage = sodium_crypto_aead_aegis128l_decrypt($ciphertext, $additional_data, $nonce, $key); // "Hello"

AEGIS-256

// generate a random key of sufficient length (32 bytes)
// This value must not be public.
$key = sodium_crypto_aead_aegis256_keygen();

// Generate random nonce value of SODIUM_CRYPTO_AEAD_AEGIS128L_NPUBBYTES length (32 bytes).
// This value should be stored along the encrypted text, but is not required to be private
$nonce = random_bytes(SODIUM_CRYPTO_AEAD_AEGIS256_NPUBBYTES);

// Additional data. This can be a user ID, email address, or empty.
$additional_data = '';

// Message to encrypt
$message = 'Hello';

// Encrypt
$ciphertext = sodium_crypto_aead_aegis256_encrypt($message, $additional_data, $nonce, $key);

// Decrypt
$decryptedMessage = sodium_crypto_aead_aegis256_decrypt($ciphertext, $additional_data, $nonce, $key); // "Hello"

向后兼容性影响

AEGIS-128LAEGIS-256 算法是 PHP 8.4 的 Sodium 扩展的新函数和常量。

sodium_compat 项目为 Sodium 扩展提供了用户空间 PHP 的补丁(polyfill)。该项目存在一个 open issue,即增加对 AEGIS-128LAEGIS-256 的支持,尽管在这方面没有做任何工作。