[OpenSSL] Support for ECC public key generation

php.internals

Dominic Luechinger

10 years ago
This is a short introduction of a feature I've been working on. Summary ------- The current OpenSSL extension only supports generating RSA key pairs. The PR [1] adds support for ECC (Elliptic curve cryptography) key generation. The corresponding bug is 61204 [2]. ------- Motivation ---------- Why needs PHP support for creating ECC key pairs? ECC has the benefit to give the same security grantees as RSA but with smaller key sizes. The current workaround without this improvement is to generate a key pair with the help of the OpenSSL CLI tool (PHP exec) or use a userland library like phpecc [3]. To protect against cryptography attack vectors like timing attack or other side-channel attacks in PHP is quite difficult. A native support would solve this issue or at least gives the responsibility to the underlying crypto library. ---------- In details ---------- The PR introduces new '$configargs' setting to openssl_pkey_new [4]. E.g.: openssl_pkey_new( array( 'curve_name' => 'secp384r1', 'private_key_type' => OPENSSL_KEYTYPE_EC, ) ); With the new ECC support it's also possible to load ECC key parameters into the openssl_pkey_new to create a key resource. openssl_pkey_new( array( 'ec' => array( 'curve_name' => 'prime256v1', 'd' => gmp_export('3138550867681922400546388175470823984762234518836963313664'), ), ) ); A use case of this possibility is e.g. the transformation on a JWK [5] to a ECC key resource. Despite the extension of openssl_pkey_new a new PHP function is introduced: openssl_get_curve_names() list names of the supported curves of the underlying OpenSSL core. This function could be used to check if a certain curve is supported and could be referenced when generating a new key pair. I'd like to outline that the ECC support is not a new feature. PHP is capable of reading and working with ECC key pairs. I've contributed some patches to improve the support. To work with ECC key pairs but not being able to generate a new key pair is the main motivation of this PR. ---------- Reference to other languages ---------------------------- The following languages have support for a ECC key pair generation: Ruby [6] Python via cryptography [7] Golang [8] Java via Bouncycastel [9] ---------------------------- Regards Dominic Luechinger [1] https://github.com/php/php-src/pull/1686 [2] https://bugs.php.net/bug.php?id=61204 [3] https://github.com/phpecc/phpecc [4] http://php.net/manual/en/function.openssl-pkey-new.php [5] https://tools.ietf.org/html/rfc7517#page-25 [6] http://ruby-doc.org/stdlib-2.0.0/libdoc/openssl/rdoc/OpenSSL/PKey/EC.html [7] https://cryptography.io/en/latest/hazmat/primitives/asymmetric/ec/ [8] https://golang.org/pkg/crypto/elliptic/#GenerateKey [9] http://www.bouncycastle.org/wiki/display/JA1/Elliptic+Curve+Key+Pair+Generation+and+Key+Factories

Scott Arciszewski

10 years ago
On Tue, Jun 14, 2016 at 8:04 PM, Dominic Luechinger <dol+php@snowgarden.ch> wrote:
> This is a short introduction of a feature I've been working on. > > Summary > ------- > The current OpenSSL extension only supports generating RSA key pairs. > The PR [1] adds support for ECC (Elliptic curve cryptography) key > generation. The corresponding bug is 61204 [2]. > ------- > > Motivation > ---------- > Why needs PHP support for creating ECC key pairs? > ECC has the benefit to give the same security grantees as RSA but with > smaller key sizes. > The current workaround without this improvement is to generate a key > pair with the help of the OpenSSL CLI tool (PHP exec) or use a userland > library like phpecc [3]. To protect against cryptography attack vectors > like timing attack or other side-channel attacks in PHP is quite > difficult. A native support would solve this issue or at least gives the > responsibility to the underlying crypto library. > ---------- > > In details > ---------- > The PR introduces new '$configargs' setting to openssl_pkey_new [4]. > E.g.: > > openssl_pkey_new( > array( > 'curve_name' => 'secp384r1', > 'private_key_type' => OPENSSL_KEYTYPE_EC, > ) > ); > > > With the new ECC support it's also possible to load ECC key parameters > into the openssl_pkey_new to create a key resource. > > openssl_pkey_new( > array( > 'ec' => array( > 'curve_name' => 'prime256v1', > 'd' => > gmp_export('3138550867681922400546388175470823984762234518836963313664'), > ), > ) > ); > > A use case of this possibility is e.g. the transformation on a JWK [5] > to a ECC key resource. > > Despite the extension of openssl_pkey_new a new PHP function is introduced: > openssl_get_curve_names() list names of the supported curves of the > underlying OpenSSL core. This function could be used to check if a > certain curve is supported and could be referenced when generating a new > key pair. > > I'd like to outline that the ECC support is not a new feature. PHP is > capable of reading and working with ECC key pairs. I've contributed some > patches to improve the support. > > To work with ECC key pairs but not being able to generate a new key pair > is the main motivation of this PR. > ---------- > > Reference to other languages > ---------------------------- > The following languages have support for a ECC key pair generation: > Ruby [6] > Python via cryptography [7] > Golang [8] > Java via Bouncycastel [9] > ---------------------------- > > Regards > > Dominic Luechinger > > > [1] https://github.com/php/php-src/pull/1686 > [2] https://bugs.php.net/bug.php?id=61204 > [3] https://github.com/phpecc/phpecc > [4] http://php.net/manual/en/function.openssl-pkey-new.php > [5] https://tools.ietf.org/html/rfc7517#page-25 > [6] > http://ruby-doc.org/stdlib-2.0.0/libdoc/openssl/rdoc/OpenSSL/PKey/EC.html > [7] https://cryptography.io/en/latest/hazmat/primitives/asymmetric/ec/ > [8] https://golang.org/pkg/crypto/elliptic/#GenerateKey > [9] > > http://www.bouncycastle.org/wiki/display/JA1/Elliptic+Curve+Key+Pair+Generation+and+Key+Factories > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php > >
While we're at it, can we also add a function to generate (ephemeral) Elliptic Curve Diffie-Hellman keys, and then use openssl_dh_compute_key() with ECDH keys? Because that would be a lot saner than having to shell_exec() to the OpenSSL binary in userland. Scott Arciszewski Chief Development Officer Paragon Initiative Enterprises <https://paragonie.com/>​

Dominic Luechinger

10 years ago
On 15/06/16 03:51, Scott Arciszewski wrote:
> While we're at it, can we also add a function to generate (ephemeral) > Elliptic Curve Diffie-Hellman keys, and then use openssl_dh_compute_key() > with ECDH keys? Because that would be a lot saner than having to > shell_exec() to the OpenSSL binary in userland.
Thank you for pointing out ECDH. It makes sense to extend the ECC support even further. What do you mean by:
> generate (ephemeral) Elliptic Curve Diffie-Hellman keys
For a ECDH to be ephemeral you could just create a new ECC key pair. This is now possible with this extension. As you pointed out the missing part is that openssl_dh_compute_key not supporting ECC keys. This was requested in the past [1]. If hacked together a proof of concept for openssl_ecdh_compute_key(). I'll push this update to a new branch. I'll send you an update if the branch is ready for testing. Regards Dominic [1] https://bugs.php.net/bug.php?id=71548