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.
(PHP 4 >= 4.2.0, PHP 5, PHP 7, PHP 8)
openssl_pkey_new — 生成一个新的私钥
openssl_pkey_new() 生成一个新的私钥和公钥对。如何获取该密钥的公共组件参见以下示例。
Note: 必须安装有效的 openssl.cnf 以保证此函数正确运行。参考有关安装的说明以获得更多信息。
成功时返回 OpenSSLAsymmetricKey 实例,错误则返回 false
。
版本 | 说明 |
---|---|
8.0.0 |
成功时此函数会返回 OpenSSLAsymmetricKey 的实例;在之前版本中,则会返回类似为
OpenSSL key 的 资源(resource)。
|
7.1.0 | 添加了 curve_name 配置参数使得可以创建 EC 密钥。 |
Example #1 Obtain the public key from a private key
<?php
$private_key = openssl_pkey_new();
$public_key_pem = openssl_pkey_get_details($private_key)['key'];
echo $public_key_pem;
$public_key = openssl_pkey_get_public($public_key_pem);
var_dump($public_key);
?>
以上例程的输出类似于:
-----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArZFsmN2P6rx1Xt7YV95o gcdlal0k3ryiIhFNzjwtRNNTXfEfBr6lUuaIJYQ8/XqEBX0hpcfuuF6tTRlonA3t WLME0QFD93YVsAaXcy76YqjjqcRRodIBphAbYyyMI/lXkQAdn7kbAmr7neSOsMYJ El9Wo4Hl4oG6e52ZnYHyqW9dxh4hX93eupR2TmcCdVf+r9xoHewP0KJYSHt7vDUX AQlWYcQiWHIadFsmL0orr6mutlXFReoHbesgKY9/3YLOu0JfxflSjIZ2JeL1NTl1 MsmODsUwgAUrwnWKKx+eQUP5g3GnSB3dPkRh9zRVRiLNWbCugyjrf3e6DgQWrW7j pwIDAQAB -----END PUBLIC KEY----- resource(5) of type (OpenSSL key)
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.
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 :)
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.
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));
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;
Getting the public key corresponding to a particular private key, through the methods provided for by OpenSSL, is a bit cumbersome. An easier way to do it is to use phpseclib, a pure PHP RSA implementation:
<?php
include('Crypt/RSA.php');
$rsa = new Crypt_RSA();
$rsa->loadKey('...');
$privatekey = $rsa->getPrivateKey();
$publickey = $rsa->getPublicKey();
?>
Doesn't require any extensions be installed. It'll use bcmath or gmp if they're available, for speed, but doesn't even require those.
If you want to change the default private key size (1024) too something else you can use the following code:
<?php
$config = array('private_key_bits' => 512);
$privKey = openssl_pkey_new($config);
?>
Mind though that the minimum number of bits is 384. Any lower will trigger an error.
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"];
?>
As you probably found, getting the public key is not as direct as you might think with this documentation.
You can easily get into messages like:
Warning: openssl_pkey_get_public(): Don't know how to get public key from this private key (the documentation lied) in D:\www\keys.php on line 4
The correct steps to get the whole thing seem to be these:
<?
$dn = array("countryName" => 'XX', "stateOrProvinceName" => 'State', "localityName" => 'SomewhereCity', "organizationName" => 'MySelf', "organizationalUnitName" => 'Whatever', "commonName" => 'mySelf', "emailAddress" => 'user@domain.com');
$privkeypass = '1234';
$numberofdays = 365;
$privkey = openssl_pkey_new();
$csr = openssl_csr_new($dn, $privkey);
$sscert = openssl_csr_sign($csr, null, $privkey, $numberofdays);
openssl_x509_export($sscert, $publickey);
openssl_pkey_export($privkey, $privatekey, $privkeypass);
openssl_csr_export($csr, $csrStr);
echo $privatekey; // Will hold the exported PriKey
echo $publickey; // Will hold the exported PubKey
echo $csrStr; // Will hold the exported Certificate
?>
Now all you need to do is to make some research on each individual function.