编程

PHP 8.2: 新增 openssl_cipher_key_length 函数

1371 2022-11-28 20:01:08

在 PHP 8.2 中,OpenSSL 扩展添加了一个名叫 openssl_cipher_key_length 的新函数,该函数返回 OpenSSL 加密所需密钥的长度(byte)。

该信息来自于 OpenSSL 基础库,因此,可以信赖。

该函数与现有的 openssl_cipher_iv_length() 函数相似,后者返回加密所需的初始化向量长度。

openssl_cipher_key_length 函数概要

openssl_cipher_key_length 函数返回给定加密算法所需密钥的长度,或者返回 false。 

对于未知的加密名,它也发送警告:openssl_cipher_key_length(): Unknown cipher algorithm

/**
 * Returns the key length for the given cipher algorithm.
 * 
 * @param string $cipher_algo Cipher algorithm name.
 * @return int|false Length of the key, or false if the cipher name is unknown
 */
function openssl_cipher_key_length(string $cipher_algo): int|false {
}

用户空间补丁 polyfill

请注意 openssl_cipher_key_length 函数使用 OpenSSL 库去检索密钥长度,OpenSSL 扩展没有对密钥长度信息进行硬编码。不过由于每个加密密钥的长度是常数,polyfill 函数可以通过对已知加密算法的密钥长度进行硬编码实现。西面就是返回每个 OpenSSL 加密算法的密钥长度,并且在碰到未知算法名时,模仿相似的行为。不过,如果 OpenSSL 以不同的或不常见的算法套件创建,下面的硬编码值则需要更新以维护对 openssl_cipher_key_length 函数的兼容性。

function openssl_cipher_key_length(string $cipher_algo): int|false {
  $length = match(strtolower($cipher_algo)) {
    'aes-128-cbc' => 16,
    'aes-128-cbc-hmac-sha1' => 16,
    'aes-128-cbc-hmac-sha256' => 16,
    'aes-128-ccm' => 16,
    'aes-128-cfb' => 16,
    'aes-128-cfb1' => 16,
    'aes-128-cfb8' => 16,
    'aes-128-ctr' => 16,
    'aes-128-ecb' => 16,
    'aes-128-gcm' => 16,
    'aes-128-ocb' => 16,
    'aes-128-ofb' => 16,
    'aes-128-wrap' => 16,
    'aes-128-wrap-pad' => 16,
    'aes-128-xts' => 32,
    'aes-192-cbc' => 24,
    'aes-192-ccm' => 24,
    'aes-192-cfb' => 24,
    'aes-192-cfb1' => 24,
    'aes-192-cfb8' => 24,
    'aes-192-ctr' => 24,
    'aes-192-ecb' => 24,
    'aes-192-gcm' => 24,
    'aes-192-ocb' => 24,
    'aes-192-ofb' => 24,
    'aes-192-wrap' => 24,
    'aes-192-wrap-pad' => 24,
    'aes-256-cbc' => 32,
    'aes-256-cbc-hmac-sha1' => 32,
    'aes-256-cbc-hmac-sha256' => 32,
    'aes-256-ccm' => 32,
    'aes-256-cfb' => 32,
    'aes-256-cfb1' => 32,
    'aes-256-cfb8' => 32,
    'aes-256-ctr' => 32,
    'aes-256-ecb' => 32,
    'aes-256-gcm' => 32,
    'aes-256-ocb' => 32,
    'aes-256-ofb' => 32,
    'aes-256-wrap' => 32,
    'aes-256-wrap-pad' => 32,
    'aes-256-xts' => 64,
    'aria-128-cbc' => 16,
    'aria-128-ccm' => 16,
    'aria-128-cfb' => 16,
    'aria-128-cfb1' => 16,
    'aria-128-cfb8' => 16,
    'aria-128-ctr' => 16,
    'aria-128-ecb' => 16,
    'aria-128-gcm' => 16,
    'aria-128-ofb' => 16,
    'aria-192-cbc' => 24,
    'aria-192-ccm' => 24,
    'aria-192-cfb' => 24,
    'aria-192-cfb1' => 24,
    'aria-192-cfb8' => 24,
    'aria-192-ctr' => 24,
    'aria-192-ecb' => 24,
    'aria-192-gcm' => 24,
    'aria-192-ofb' => 24,
    'aria-256-cbc' => 32,
    'aria-256-ccm' => 32,
    'aria-256-cfb' => 32,
    'aria-256-cfb1' => 32,
    'aria-256-cfb8' => 32,
    'aria-256-ctr' => 32,
    'aria-256-ecb' => 32,
    'aria-256-gcm' => 32,
    'aria-256-ofb' => 32,
    'camellia-128-cbc' => 16,
    'camellia-128-cfb' => 16,
    'camellia-128-cfb1' => 16,
    'camellia-128-cfb8' => 16,
    'camellia-128-ctr' => 16,
    'camellia-128-ecb' => 16,
    'camellia-128-ofb' => 16,
    'camellia-192-cbc' => 24,
    'camellia-192-cfb' => 24,
    'camellia-192-cfb1' => 24,
    'camellia-192-cfb8' => 24,
    'camellia-192-ctr' => 24,
    'camellia-192-ecb' => 24,
    'camellia-192-ofb' => 24,
    'camellia-256-cbc' => 32,
    'camellia-256-cfb' => 32,
    'camellia-256-cfb1' => 32,
    'camellia-256-cfb8' => 32,
    'camellia-256-ctr' => 32,
    'camellia-256-ecb' => 32,
    'camellia-256-ofb' => 32,
    'chacha20' => 32,
    'chacha20-poly1305' => 32,
    'des-ede-cbc' => 16,
    'des-ede-cfb' => 16,
    'des-ede-ecb' => 16,
    'des-ede-ofb' => 16,
    'des-ede3-cbc' => 24,
    'des-ede3-cfb' => 24,
    'des-ede3-cfb1' => 24,
    'des-ede3-cfb8' => 24,
    'des-ede3-ecb' => 24,
    'des-ede3-ofb' => 24,
    'des3-wrap' => 24,
    'sm4-cbc' => 16,
    'sm4-cfb' => 16,
    'sm4-ctr' => 16,
    'sm4-ecb' => 16,
    'sm4-ofb' => 16,
    default => false,
  };

  if ($length === false) {
      trigger_error('openssl_cipher_key_length(): Unknown cipher algorithm', E_USER_WARNING);
  }

  return $length;
}

向后兼容性影响

openssl_cipher_key_length 是一个在 PHP 8.2 中新增到 OpenSSL 扩展的函数。可以使用补丁去兼容老版本,尽管通过用户空间 PHP 函数对已知加密算法密钥长度进行硬编码并不完美 。