php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #76676 OPENSSL_KEYTYPE_EC (and others) not supported by openssl_public_encrypt()
Submitted: 2018-07-28 13:47 UTC Modified: 2022-11-25 15:08 UTC
Votes:15
Avg. Score:4.3 ± 1.2
Reproduced:15 of 15 (100.0%)
Same Version:3 (20.0%)
Same OS:2 (13.3%)
From: kaplan@php.net Assigned: bukka (profile)
Status: Closed Package: OpenSSL related
PHP Version: 7.1.20 OS:
Private report: No CVE-ID: None
 [2018-07-28 13:47 UTC] kaplan@php.net
Description:
------------
Comparing key types supported by php_openssl_is_private_key() to the ones supported by openssl_public_key() shows many are missing.

php_openssl_is_private_key recognizes: 
EVP_PKEY_RSA / EVP_PKEY_RSA2
EVP_PKEY_DSA / EVP_PKEY_DSA1 / EVP_PKEY_DSA2 / EVP_PKEY_DSA3 / EVP_PKEY_DSA4
EVP_PKEY_DH
EVP_PKEY_EC

openssl_private_encrypt supports
EVP_PKEY_RSA / EVP_PKEY_RSA2

openssl_private_decrypt supports
EVP_PKEY_RSA / EVP_PKEY_RSA2

openssl_public_decrypt supports
EVP_PKEY_RSA / EVP_PKEY_RSA2

Maybe also use EVP_PKEY_base_id() as in openssl_pkey_get_details() which does support all the keys as php_openssl_is_private_key().

Tested in 7.1.14, 7.2.6 and master (July 26th, 2018).

Test script:
---------------
<?php
$pair = generateKeyPair(true);
$public = $pair['public'];

$ciphertext = "111-11-1111";
$res = openssl_public_encrypt($ciphertext, $enc, $public, OPENSSL_PKCS1_OAEP_PADDING);
if($res){
    var_dump(bin2hex($enc));
} else {
    echo "Failed to encrypt :(";
}

function generateKeyPair(bool $ec){
    $params = $ec ? [
        'private_key_bits' => 384,
        'private_key_type' => OPENSSL_KEYTYPE_EC,
        'curve_name' => 'secp384r1'
    ] : [
        'private_key_bits' => 3072,
        'private_key_type' => OPENSSL_KEYTYPE_RSA
    ];
    
    $res = openssl_pkey_new($params);
    openssl_pkey_export($res, $privKey);

    $pubKey = openssl_pkey_get_details($res);
    $pubKey = $pubKey["key"];
    
    openssl_free_key($res);
    return ['private'=>$privKey, 'public'=>$pubKey];
}

?>

Expected result:
----------------
1. for OPENSSL_KEYTYPE_EC to be suppprted.
2. for missing keytype be part of the error message.

Actual result:
--------------
Warning: openssl_public_encrypt(): key type not supported in this PHP build!

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2022-11-25 15:00 UTC] bukka@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: bukka
 [2022-11-25 15:00 UTC] bukka@php.net
So OPENSSL_KEYTYPE_EC is now supported for openssl_pkey_new so that part works for me fine with PHP 8.1. However encrypt doesn't work here but the reason that secp384r1 cannot be used for encryption but only for signing.

It means nothing to do here so closing.
 [2022-11-25 15:08 UTC] bukka@php.net
Just to add, the supported key types are only those that supports encryption. This is all checked by OpenSSL so  errors can be seen by calling openssl_error_string().
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Apr 20 02:01:29 2024 UTC