为什么我不能在 PHP OpenSSL 中为 EC 使用小于 384 位的密钥长度?

Why can't I use key lengths < 384bit for EC in PHP OpenSSL?

对我来说很明显,384 位 RSA 密钥非常不安全。 关于 RSA 有一个类似的问题:Why is keysize < 384 bits deemed too small for openssl_pkey_new()?

但是,384 位 EC 密钥目前被认为非常安全。 就我而言,384 位太长,这就是为什么我想使用 256 位密钥。

为什么下面的代码会抛出 Warning: openssl_pkey_new(): private key length is too short; it needs to be at least 384 bits, not 256

<?php
$config = array(
    "private_key_type" => OPENSSL_KEYTYPE_EC,
    "private_key_bits" => 256,
    "curve_name" => "prime256v1"
);

// Create the private and public key
$res = openssl_pkey_new($config);

是我做错了什么,还是 openssl_pkey_new() 对 RSA 和 EC 的要求真的相同?

PHP source code 可以看出 openssl_pkey_new 调用 php_openssl_generate_private_key,它检查通过 private_key_bits 传递的密钥大小,而不管密钥类型和 returns 如果大小小于 MIN_KEY_LENGTH,则发布错误,定义为 384。这适用于当前版本 (v 7.4.7) 到 v 4.0。对比当前版本,v 4.0 支持RSA密钥,因此可以得出384位的密钥大小是指RSA密钥[=26] =]

因为 EC 密钥比具有相当安全性的 RSA 密钥小(NIST and ECRYPT第 7 章推荐的密钥大小) ,特定于密钥类型的检查会更有用。 384 位的 EC 密钥的最小长度是不合理的。但对于 RSA,从今天的角度来看,384 位的值也太小了。

php_openssl_generate_private_key中还可以看出,在密钥生成期间,密钥大小仅用于 RSA、DSA 和 DH 密钥的上下文中,但根本不用于 EC 密钥的上下文中,其中改为使用曲线名称。 IE。用 private_key_bits 指定的密钥大小对于 EC 密钥的上下文不是必需的(并且可能不是预期的)因此应该被省略,这也避免了错误消息:

<?php
$config = array(
    "private_key_type" => OPENSSL_KEYTYPE_EC,
    "curve_name" => "prime256v1"
);

$res = openssl_pkey_new($config);
print_r(openssl_pkey_get_details($res));
?>

为了完整性:如果未使用 private_key_bits 指定密钥大小,则使用 OpenSSL 配置文件中的默认值对其进行初始化,当前版本为 2048 位。此值对应于 RSA 的当前建议(NIST, Recommendation for Key Management2.2.1 Recommended Key Sizes and Algorithms),也是上下文中未触发错误消息的原因EC 密钥。