PHP 8.5.0 Beta 3 available for testing

openssl_pkey_new

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

openssl_pkey_new新規に秘密鍵を生成する

説明

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

openssl_pkey_new() は、 新しい秘密鍵を生成します。 鍵の公開部を取得する方法は、以下の例に示します。

注意: この関数を正しく動作させるには、正しい形式の openssl.cnf をインストールしておく必要があります。 詳細な情報は、インストールについてのセクション を参照ください。

パラメータ

options

options を使うと、 鍵の生成処理を微調整(例:ビット数やパラメータの指定) することができます。 これらのオプションは、鍵生成に用いられるアルゴリズム固有のパラメータ、 または指定がない場合に CSR 生成でも用いられる汎用オプションのいずれかです。 CSR に関する options の使用方法の詳細については、 openssl_csr_new() を参照ください。 これらのオプションのうち、鍵生成に使用されるのは private_key_bits, private_key_type, curve_name, config のみになります。 連想配列に特定のキーが含まれている場合、アルゴリズム固有のオプションが使用されます。

  • RSA パラメータを設定するためのキーは "rsa" です。
    options type format required description
    "n" string binary number yes modulus
    "e" string binary number no public exponent
    "d" string binary number yes private exponent
    "p" string binary number no prime 1
    "q" string binary number no prime 2
    "dmp1" string binary number no exponent1, d mod (p-1)
    "dmq1" string binary number no exponent2, d mod (q-1)
    "iqmp" string binary number no coefficient, (inverse of q) mod p
  • DSA パラメータを設定するためのキーは "dsa" です。
    options type format required description
    "p" string binary number no prime number (public)
    "q" string binary number no 160-bit subprime, q | p-1 (public)
    "g" string binary number no generator of subgroup (public)
    "priv_key" string PEM key no private key x
    "pub_key" string PEM key no public key y = g^x
  • DH (Diffie–Hellman key exchange) パラメータを設定するためのキーは "dh" です。
    Options Format Required 説明
    "p" string binary number no prime number (shared)
    "g" string binary number no generator of Z_p (shared)
    "priv_key" string PEM key no private DH value x
    "pub_key" string PEM key no public DH value g^x
  • Elliptic curve パラメータを設定するためのキーは "ec" です。
    Options Format Required 説明
    "curve_name" string name no name of curve, see openssl_get_curve_names()
    "p" string binary number no prime of the field for curve over Fp
    "a" string binary number no coofecient a of the curve for Fp: y^2 mod p = x^3 + ax + b mod p
    "b" string binary number no coofecient b of the curve for Fp: y^2 mod p = x^3 + ax + b mod p
    "seed" string binary number no optional random number seed used to generate coefficient b
    "generator" string binary encoded point no curve generator point
    "g_x" string binary number no curver generator point x coordinat
    "g_y" string binary number no curver generator point y coordinat
    "cofactor" string binary number no curve cofactor
    "order" string binary number no curve order
    "x" string binary number no x coordinate (public)
    "y" string binary number no y coordinate (public)
    "d" string binary number no private key
  • Curve25519 と Curve448 パラメータを設定するためのキーは "x25519", "x448", "ed25519", "ed448" です。
    Options Format Required 説明
    "priv_key" string PEM key no private key
    "pub_key" string PEM key no public key

戻り値

成功した場合に、OpenSSLAsymmetricKey クラスのインスタンスを返します。 エラー時に false を返します。

変更履歴

バージョン 説明
8.4.0 Curve25519 と Curve448 ベースの鍵を生成する機能がサポートされました。 使える連想配列のフィールドは x25519, ed25519, x448, ed448 です。
8.3.0 カスタムの EC パラメータを使って、 EC 鍵を生成する機能がサポートされました。 EC 鍵の生成に使うオプションを以下に示します: p, a, b, seed, generator, g_x, g_y, cofactor, order
8.0.0 成功した場合に、 この関数は OpenSSLAsymmetricKey クラスのインスタンスを返すようになりました。 これより前のバージョンでは、 OpenSSL key 型のリソースを返していました。
7.1.0 楕円曲線アルゴリズムをベースに EC キーを作成できるようにするため、 options パラメータの curve_name キーが追加されました。

例1 秘密鍵から、公開鍵を取得する

<?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);

?>

上の例の出力は、 たとえば以下のようになります。

// Output prior to PHP 8.0.0; note, the function returns a resource
-----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)

// Output as of PHP 8.0.0; note, the function returns an object
-----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) {
}

例2 RSA 鍵を生成する

<?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
8 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