3

It is obvious to me that a 384bit RSA Key is tremendously insecure. There is a similar question regarding RSA: Why is keysize < 384 bits deemed too small for openssl_pkey_new()?

However, a 384bit EC key is currently seen as extremely secure. In my case, 384bit are too long which is why I'd like to use 256bit keys.

Why does the following code throw 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);

Am I doing something wrong or does openssl_pkey_new() really have the same requirements for RSA and EC?

dmuensterer
  • 1,875
  • 11
  • 26
  • 3
    `openssl_pkey_new` calls `php_openssl_generate_private_key`, which checks if the specified key size is less than `MIN_KEY_LENGTH` defined as `384`, [here](https://github.com/php/php-src/blob/PHP-7.4.7/ext/openssl/openssl.c). This applies to the current version down to v 4.0, which only supports RSA keys. So this probably refers to RSA (whereby 384 is also too small for RSA according to _today's_ criteria). In the context of EC keys, the key size is not used at all during generation, but only the curve name. Simply omit the key size in the context of EC keys, then the error won't be triggered. – Topaco Jun 17 '20 at 15:03
  • 1
    @Topaco: Unfortunately much php documentation is terrible, so stackoverflow has to function as php documentation. Can you please make this an answer? – President James K. Polk Jun 17 '20 at 20:04
  • Topaco, thank you very much. I got this to work thanks to your advice. Yes, please make this an answer, I'll be glad to accept it! – dmuensterer Jun 17 '20 at 20:15

1 Answers1

1

From the PHP source code it can be seen that openssl_pkey_new calls php_openssl_generate_private_key, which checks the key size passed with private_key_bits regardless of the key type and returns the posted error if the size is less than MIN_KEY_LENGTH, which is defined as 384. This applies to the current version (v 7.4.7) down to v 4.0. In contrast to the current version, v 4.0 only supports RSA keys, so it can be concluded from this that the key size of 384 bits refers to RSA keys.

Since EC keys are smaller than RSA keys with comparable security (NIST and ECRYPT, Chapter 7, Recommended Key Sizes), a key type-specific check would be more useful. A minimum length for EC keys of 384 bits is not reasonable. But also for RSA the value of 384 bits is too small from today's view.

In php_openssl_generate_private_key it can also be seen that during key generation the key size is only used in the context of RSA, DSA and DH keys, but not at all in the context of EC keys, where the curve name is used instead. I.e. the key size specified with private_key_bits is not required for the context of EC keys (and probably not intended) and should therefore be omitted, which also avoids the error message:

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

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

For completeness: If the key size is not specified with private_key_bits, it is initialized with a default value from the OpenSSL configuration file, which is 2048 bits for the current version. This value corresponds to the current recommendation for RSA (NIST, Recommendation for Key Management, 2.2.1 Recommended Key Sizes and Algorithms) and is also the reason why the error message is not triggered in the context of EC keys.

Topaco
  • 40,594
  • 4
  • 35
  • 62