PHP 8.5.0 Alpha 2 available for testing

openssl_pkey_new

(PHP 4 >= 4.2.0, PHP 5, PHP 7, PHP 8)

openssl_pkey_newGenera una nueva clave privada

Descripción

openssl_pkey_new(?array $options = null): OpenSSLAsymmetricKey|false

openssl_pkey_new() genera una nueva clave privada. Cómo obtener el componente público de la clave se demuestra en un ejemplo a continuación.

Nota: Debe existir un archivo openssl.cnf válido e instalado para que esta función opere correctamente. Ver las notas encontradas en la sección concerniente a la instalación para más información.

Parámetros

options

Es posible afinar la generación de claves (por ejemplo, especificando el número de bits o los parámetros) mediante el argumento options. Estas opciones pueden ser parámetros específicos del algoritmo utilizados para la generación de claves, u opciones genéricas también utilizadas para la generación de CSR si no se especifican. Consulte openssl_csr_new() para obtener más información sobre el uso de options para un CSR. Entre estas opciones, solo private_key_bits, private_key_type, curve_name, y config se utilizan para la generación de claves. Las opciones específicas de un algoritmo se utilizan si el array asociativo incluye una de las claves específicas.

  • Clave "rsa" para definir los parámetros RSA.
    options type format requis description
    "n" string número binario módulo
    "e" string número binario no exponente público
    "d" string número binario exponente privado
    "p" string número binario no primer 1
    "q" string número binario no primer 2
    "dmp1" string número binario no exponent1, d mod (p-1)
    "dmq1" string número binario no exponent2, d mod (q-1)
    "iqmp" string número binario no coeficiente, (inverso de q) mod p
  • Clave "dsa" para definir los parámetros DSA.
    options type format requis description
    "p" string número binario no número primo (público)
    "q" string número binario no 160 bits sub-prime, q | p-1 (público)
    "g" string número binario no generador del subgrupo (público)
    "priv_key" string clave PEM no clave privada x
    "pub_key" string clave PEM no clave pública y = g^x
  • Clave "dh" para los parámetros DH (intercambio de claves Diffie–Hellman).
    Options Tipo Format Requis Descripción
    "p" string número binario no número primo (compartido)
    "g" string número binario no generador de Z_p (compartido)
    "priv_key" string clave PEM no valor DH privado x
    "pub_key" string clave PEM no valor DH público g^x
  • Clave "ec" para los parámetros de curva elíptica
    Options Tipo Format Requis Descripción
    "curve_name" string nombre no nombre de la curva, ver openssl_get_curve_names()
    "p" string número binario no número primo del campo para la curva sobre Fp
    "a" string número binario no coeficiente a de la curva para Fp : y^2 mod p = x^3 + ax + b mod p
    "b" string número binario no coeficiente b de la curva para Fp : y^2 mod p = x^3 + ax + b mod p
    "seed" string número binario no número aleatorio opcional utilizado para generar el coeficiente b
    "generator" string punto codificado en binario no punto generador de la curva
    "g_x" string número binario no coordenada x del punto generador de la curva
    "g_y" string número binario no coordenada y del punto generador de la curva
    "cofactor" string número binario no cofactor de la curva
    "order" string número binario no orden de la curva
    "x" string número binario no coordenada x (pública)
    "y" string número binario no coordenada y (pública)
    "d" string número binario no clave privada
  • Claves "x25519", "x448", "ed25519", "ed448" para los parámetros Curve25519 y Curve448.
    Options Tipo Format Requis Descripción
    "priv_key" string clave PEM no clave privada
    "pub_key" string clave PEM no clave pública

Valores devueltos

Devuelve una instancia de OpenSSLAsymmetricKey en caso de éxito, false en caso de error.

Historial de cambios

Versión Descripción
8.4.0 Se añadió el soporte para claves basadas en Curve25519 y Curve448 con la introducción de los campos x25519, ed25519, x448, y ed448.
8.3.0 Se añadió el soporte para la generación de claves EC con parámetros EC personalizados. Más específicamente, con la introducción de las opciones EC: p, a, b, seed, generator, g_x, g_y, cofactor, y order.
8.0.0 En caso de éxito, esta función devuelve ahora una instancia de OpenSSLAsymmetricKey; anteriormente, se devolvía un resource de tipo OpenSSL key.
7.1.0 Se añadió la opción curve_name para permitir la creación de claves EC.

Ejemplos

Ejemplo #1 Obtener la clave pública a partir de una clave privada

<?php

$private_key
= openssl_pkey_new();
$public_key_pem = openssl_pkey_get_details($private_key)['key'];
echo
$public_key_pem, PHP_EOL;

$public_key = openssl_pkey_get_public($public_key_pem);
var_dump($public_key);

?>

Resultado del ejemplo anterior es similar a :

// Resultado antes de PHP 8.0.0; note que la función devuelve un recurso
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwknBFEherZe74BiRjTFA
hqwZ1SK7brwq7C/afnLXKhRR7jnrpfM0ypC46q8xz5UZswenZakJ7kd5fls+r4Bv
3P8XsKYLTh2m1GiWQhV1g77cNIN4qNWh70PiDO3fB2446o1LBgToQYuRZS5YQRfJ
rVD0ysgtVcCU9tjaey28HlgApOpYFTaaKPj2MBmEYpMC+kG2HhL12GfpHUi2eiXI
dXT2WskWHWvUrmQ7fJIfI92JlDokV62DH/q1oiedLs9OPNb0rL1aAmYdzaVN6XNH
x/o4Lh125v2vAPV9E3fZCDc/HDEUaahpjanMiCQEgEDp5Hr+CRkvERT5/ydN+p08
5wIDAQAB
-----END PUBLIC KEY-----
resource(6) of type (OpenSSL key)

// Resultado a partir de PHP 8.0.0; note que la función devuelve un objeto
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwknBFEherZe74BiRjTFA
hqwZ1SK7brwq7C/afnLXKhRR7jnrpfM0ypC46q8xz5UZswenZakJ7kd5fls+r4Bv
3P8XsKYLTh2m1GiWQhV1g77cNIN4qNWh70PiDO3fB2446o1LBgToQYuRZS5YQRfJ
rVD0ysgtVcCU9tjaey28HlgApOpYFTaaKPj2MBmEYpMC+kG2HhL12GfpHUi2eiXI
dXT2WskWHWvUrmQ7fJIfI92JlDokV62DH/q1oiedLs9OPNb0rL1aAmYdzaVN6XNH
x/o4Lh125v2vAPV9E3fZCDc/HDEUaahpjanMiCQEgEDp5Hr+CRkvERT5/ydN+p08
5wIDAQAB
-----END PUBLIC KEY-----

object(OpenSSLAsymmetricKey)#2 (0) {
}

Ejemplo #2 Generación de una clave RSA a partir de parámetros

<?php

$nhex
= "BBF82F090682CE9C2338AC2B9DA871F7368D07EED41043A440D6B6F07454F51F" .
"B8DFBAAF035C02AB61EA48CEEB6FCD4876ED520D60E1EC4619719D8A5B8B807F" .
"AFB8E0A3DFC737723EE6B4B7D93A2584EE6A649D060953748834B2454598394E" .
"E0AAB12D7B61A51F527A9A41F6C1687FE2537298CA2A8F5946F8E5FD091DBDCB";

$ehex = "11";
$dhex = "A5DAFC5341FAF289C4B988DB30C1CDF83F31251E0668B42784813801579641B2" .
"9410B3C7998D6BC465745E5C392669D6870DA2C082A939E37FDCB82EC93EDAC9" .
"7FF3AD5950ACCFBC111C76F1A9529444E56AAF68C56C092CD38DC3BEF5D20A93" .
"9926ED4F74A13EDDFBE1A1CECC4894AF9428C2B7B8883FE4463A4BC85B1CB3C1";

$phex = "EECFAE81B1B9B3C908810B10A1B5600199EB9F44AEF4FDA493B81A9E3D84F632" .
"124EF0236E5D1E3B7E28FAE7AA040A2D5B252176459D1F397541BA2A58FB6599";

$qhex = "C97FB1F027F453F6341233EAAAD1D9353F6C42D08866B1D05A0F2035028B9D86" .
"9840B41666B42E92EA0DA3B43204B5CFCE3352524D0416A5A441E700AF461503";

$dphex = "11";
$dqhex = "11";
$qinvhex = "b06c4fdabb6301198d265bdbae9423b380f271f73453885093077fcd39e2119f" .
"c98632154f5883b167a967bf402b4e9e2e0f9656e698ea3666edfb25798039f7";

$rsa= openssl_pkey_new([
'rsa' => [
'n' => hex2bin($nhex),
'e' => hex2bin($ehex),
'd' => hex2bin($dhex),
'p' => hex2bin($phex),
'q' => hex2bin($qhex),
'dmp1' => hex2bin($dphex),
'dmq1' => hex2bin($dqhex),
'iqmp' => hex2bin($qinvhex),
],
]);
$details = openssl_pkey_get_details($rsa);
var_dump($details);

?>
add a note

User Contributed Notes 8 notes

up
49
dirt at awoms dot com
12 years ago
Working example:

$config = array(
"digest_alg" => "sha512",
"private_key_bits" => 4096,
"private_key_type" => OPENSSL_KEYTYPE_RSA,
);

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

// Extract the private key from $res to $privKey
openssl_pkey_export($res, $privKey);

// Extract the public key from $res to $pubKey
$pubKey = openssl_pkey_get_details($res);
$pubKey = $pubKey["key"];

$data = 'plaintext data goes here';

// Encrypt the data to $encrypted using the public key
openssl_public_encrypt($data, $encrypted, $pubKey);

// Decrypt the data using the private key and store the results in $decrypted
openssl_private_decrypt($encrypted, $decrypted, $privKey);

echo $decrypted;
up
18
gomez dot alejandre at gmail dot com
6 years ago
Not forget the $configArgs for windows users :D, or the method throws a error with the primary key

//write your configurations :D
$configargs = array(
"config" => "C:/xampp/php/extras/openssl/openssl.cnf",
'private_key_bits'=> 2048,
'default_md' => "sha256",
);

// Create the keypair
$res=openssl_pkey_new($configargs);
// Get private key
openssl_pkey_export($res, $privKey,NULL,$configargs);

and it's for all methods ._ .

a full implementation example here.

https://gist.github.com/DuckHunter213/269a0efd17e709f7f1f177ae7da46ad1

this error take me 3 full days you'r welcome :)
up
12
scott at brynen dot com
10 years ago
If you try and generate a new key using openssl_pkey_new(), and need to specify the size of the key, the key MUST be type-bound to integer

// works
$keysize = 1024;
$ssl = openssl_pkey_new (array('private_key_bits' => $keysize));

// fails
$keysize = "1024";
$ssl = openssl_pkey_new (array('private_key_bits' => $keysize));

// works (force to int)
$keysize = "1024";
$ssl = openssl_pkey_new (array('private_key_bits' => (int)$keysize));
up
3
Andrew
3 years ago
It's not documented here but you can also create ECC keys from existing key parameters (e.g. from JWK):

<?php
$key
= openssl_pkey_new([
'ec' => [
'curve_name' => 'prime256v1',
'x' => $someXValue,
'y' => $someYValue,
'd' => $someDValue
]
]);
?>

You can just provide x/y if it's a public key, or you can just provide d if it's a private key.
up
5
Brad
17 years ago
It's easier than all that, if you just want the keys:

<?php
// Create the keypair
$res=openssl_pkey_new();

// Get private key
openssl_pkey_export($res, $privkey);

// Get public key
$pubkey=openssl_pkey_get_details($res);
$pubkey=$pubkey["key"];
?>
up
1
Eno_CN at qq dot com
6 months ago
Some examples for generating EC keypair

EC - generate keypair with curve_name

<?php
/*
* Custom parameters x, y, and d are not supported with SM2 in OpenSSL 3.x.
* Directly creating EVP_PKEY_CTX using EVP_PKEY_CTX_new_from_name(NULL, "SM2", NULL)
* will result in generating incorrect private keys (which cannot be correctly recognized
* by existing external applications based on the SM2 algorithm).
*/
$curve_name = 'SM2';
$pkey = openssl_pkey_new(array(
'ec'=> array(
'curve_name' => $curve_name,
)
));

$details = openssl_pkey_get_details($pkey);
var_dump($details);
$pubkey = $details['key'];
openssl_pkey_export($pkey, $prikey);
echo
'Private Key:', PHP_EOL, $prikey, PHP_EOL;
echo
'Public Key:', PHP_EOL, $pubkey, PHP_EOL;
?>

EC - generate keypair with custom params (OSCCA WAPIP192v1 Elliptic curve)

<?php
$d
= hex2bin('8D0AC65AAEA0D6B96254C65817D4A143A9E7A03876F1A37D'); // private key binary
$x = hex2bin('98E07AAD50C31F9189EBE6B8B5C70E5DEE59D7A8BC344CC6'); // public key x binary
$y = hex2bin('6109D3D96E52D0867B9D05D72D07BE5876A3D973E0E96792'); // public key y binary

$p = hex2bin('BDB6F4FE3E8B1D9E0DA8C0D46F4C318CEFE4AFE3B6B8551F');
$a = hex2bin('BB8E5E8FBC115E139FE6A814FE48AAA6F0ADA1AA5DF91985');
$b = hex2bin('1854BEBDC31B21B7AEFC80AB0ECD10D5B1B3308E6DBF11C1');
$g_x = hex2bin('4AD5F7048DE709AD51236DE65E4D4B482C836DC6E4106640');
$g_y = hex2bin('02BB3A02D4AAADACAE24817A4CA3A1B014B5270432DB27D2');
$order = hex2bin('BDB6F4FE3E8B1D9E0DA8C0D40FC962195DFAE76F56564677');

$pkey = openssl_pkey_new(array(
'ec'=> array(
'p' => $p,
'a' => $a,
'b' => $b,
'order' => $order,
'g_x' => $g_x,
'g_y' => $g_y,
//'d' => $d, // import the private key to generate keypairs
)
));

$details = openssl_pkey_get_details($pkey);
var_dump($details);
$pubkey = $details['key'];
openssl_pkey_export($pkey, $prikey);
echo
'Private Key:', PHP_EOL, $prikey, PHP_EOL;
echo
'Public Key:', PHP_EOL, $pubkey, PHP_EOL;
?>

EC - generate keypair with custom params (SM2 curve)

<?php
$p
= hex2bin('FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF');
$a = hex2bin('FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC');
$b = hex2bin('28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93');
$g_x = hex2bin('32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7');
$g_y = hex2bin('BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0');
$order = hex2bin('FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123');

/*
* Custom parameters x, y, and d are not supported with SM2 in OpenSSL 3.x.
* Directly creating EVP_PKEY_CTX using EVP_PKEY_CTX_new_from_name(NULL, "SM2", NULL)
* will result in generating incorrect private keys (which cannot be correctly recognized
* by existing external applications based on the SM2 algorithm).
*/
$pkey = openssl_pkey_new(array(
'ec'=> array(
'p' => $p,
'a' => $a,
'b' => $b,
'order' => $order,
'g_x' => $g_x,
'g_y' => $g_y,
)
));

/*
* It is not entirely the same as generating keys through the SM2 curve naming method.
* So the generated key will be in PKCS8 format to store algorithm information.
*/
$details = openssl_pkey_get_details($pkey);
var_dump($details);
$pubkey = $details['key'];
openssl_pkey_export($pkey, $prikey);
echo
'Private Key:', PHP_EOL, $prikey, PHP_EOL;
echo
'Public Key:', PHP_EOL, $pubkey, PHP_EOL;
?>
up
0
Jan
6 years ago
In case this function returns false, then check your openssl.cnf and make sure that in the [req] section of this file the entry default_bits is not commented out.
up
-1
dodginess at yahoo dot com
8 years ago
If you're using openssl_pkey_new() in conjunction with openssl_csr_new() and want to change the CSR digest algorithm as well as specify a custom key size, the configuration override should be defined once and sent to both functions:

<?php
$config
= array(
'digest_alg' => 'sha1',
'private_key_bits' => 2048,
'private_key_type' => OPENSSL_KEYTYPE_RSA,
);

$privkey = openssl_pkey_new($config);

$csr = openssl_csr_new($dn, $privkey, $config);
?>

Although openssl_pkey_new() will accept the 'digest_alg' argument it won't use it, and setting the value has no effect unless you also set this value for openssl_csr_new(). The reason for this is that the $config array is acting as a drop-in replacement for the values found in the openssl.cnf file, so it must contain all of the override values that you need even if the function they're being sent to won't use them.

Also, if you change the 'digest_alg' to something like 'sha256' and still get an MD5 signed CSR check your openssl.cnf file to see whether the digest algorithm you want to use is actually supported.
To Top