PHP Conference Japan 2024

openssl_pkey_new

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

openssl_pkey_new產生新的私鑰

說明

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

openssl_pkey_new() 產生一個新的私鑰。以下範例顯示如何取得金鑰的公鑰部分。

注意您需要安裝有效的 openssl.cnf 才能使此函式正常運作。詳情請參閱安裝章節下的注意事項。

參數

選項 (options)

您可以使用 options 微調金鑰產生(例如指定位元數)。有關 options 的更多資訊,請參見 openssl_csr_new()

回傳值

成功時返回 pkey 的 OpenSSLAsymmetricKey 實例,錯誤時返回 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));

// 可行(強制轉換為整數)
$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