PHP Conference Japan 2024

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 微调密钥生成(例如指定位数)。有关 options 的更多信息,请参阅 openssl_csr_new()

返回值

如果成功,则返回一个 OpenSSLAsymmetricKey 实例,表示 pkey;如果出错,则返回 false

变更日志

版本 描述
8.0.0 如果成功,此函数现在返回一个 OpenSSLAsymmetricKey 实例;以前,返回一个类型为 OpenSSL key资源
7.1.0 添加了 options 参数的 curve_name 键,以便可以基于椭圆曲线算法创建 EC 密钥。

示例

示例 #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) {
}
添加注释

用户贡献的注释 7 条注释

dirt at awoms dot com
11 年前
工作示例

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

// 创建私钥和公钥
$res = openssl_pkey_new($config);

// 将私钥从 $res 提取到 $privKey
openssl_pkey_export($res, $privKey);

// 将公钥从 $res 提取到 $pubKey
$pubKey = openssl_pkey_get_details($res);
$pubKey = $pubKey["key"];

$data = 'plaintext data goes here';

// 使用公钥将数据加密到 $encrypted
openssl_public_encrypt($data, $encrypted, $pubKey);

// 使用私钥解密数据并将结果存储到 $decrypted 中
openssl_private_decrypt($encrypted, $decrypted, $privKey);

echo $decrypted;
gomez dot alejandre at gmail dot com
5 年前
不要忘记 Windows 用户的 $configArgs :D,否则该方法会抛出一个关于主密钥的错误

// 写入您的配置 :D
$configargs = array(
"config" => "C:/xampp/php/extras/openssl/openssl.cnf",
'private_key_bits'=> 2048,
'default_md' => "sha256",
);

// 创建密钥对
$res=openssl_pkey_new($configargs);
// 获取私钥
openssl_pkey_export($res, $privKey,NULL,$configargs);

它适用于所有方法 ._ .

这里有一个完整的实现示例。

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

这个错误让我花了 3 天时间,欢迎您:)
scott at brynen dot com
9 年前
如果您尝试使用 openssl_pkey_new() 生成新密钥,并且需要指定密钥的大小,则密钥必须绑定到整数类型

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

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

// 可行(强制转换为 int)
$keysize = "1024";
$ssl = openssl_pkey_new (array('private_key_bits' => (int)$keysize));
Andrew
3 年前
这里没有记录,但您也可以从现有的密钥参数(例如来自 JWK)创建 ECC 密钥

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

如果它是公钥,您可以只提供 x/y,或者如果它是私钥,您可以只提供 d。
Brad
16 年前
如果只是想要密钥,则更简单

<?php
// 创建密钥对
$res=openssl_pkey_new();

// 获取私钥
openssl_pkey_export($res, $privkey);

// 获取公钥
$pubkey=openssl_pkey_get_details($res);
$pubkey=$pubkey["key"];
?>
Jan
5 年前
如果此函数返回 false,请检查您的 openssl.cnf,并确保在此文件的 [req] 部分中,default_bits 条目未被注释掉。
dodginess at yahoo dot com
7 年前
如果您将 openssl_pkey_new() 与 openssl_csr_new() 结合使用,并且想要更改 CSR 摘要算法以及指定自定义密钥大小,则应一次定义配置覆盖并将其发送到这两个函数



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

尽管 openssl_pkey_new() 函数可以接收 'digest_alg' 参数,但它不会使用该参数,并且除非您也为 openssl_csr_new() 函数设置了该值,否则设置该值无效。原因是 $config 数组充当了 openssl.cnf 文件中找到的值的直接替换,因此它必须包含您需要的所有覆盖值,即使发送到的函数不会使用它们。

此外,如果您将 'digest_alg' 更改为 'sha256' 等,但仍然得到一个使用 MD5 签名的 CSR,请检查您的 openssl.cnf 文件,以查看您要使用的摘要算法是否实际受支持。
To Top