2024 年 PHP Conference Japan

openssl_sign

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

openssl_sign產生簽章

說明

openssl_sign(
    字串 $data,
    字串 &$signature,
    #[\SensitiveParameter] OpenSSLAsymmetricKey|OpenSSLCertificate|陣列|字串 $private_key,
    字串|整數 $algorithm = OPENSSL_ALGO_SHA1
): 布林值

openssl_sign() 函式會使用與 private_key 相關聯的私鑰產生加密數位簽章,來計算指定 data 的簽章。請注意,資料本身並不會被加密。

參數

data

您想要簽署的資料字串

signature

如果呼叫成功,簽章會回傳至 signature

private_key

OpenSSLAsymmetricKey - 一個由 openssl_get_privatekey() 回傳的密鑰

string - 一個 PEM 格式的密鑰

algorithm

int - 簽章演算法 之一。

string - 由 openssl_get_md_methods() 回傳的有效字串,例如 "sha256WithRSAEncryption" 或 "sha384"。

回傳值

成功時回傳 true,失敗時回傳 false

更新日誌

版本 說明
8.0.0 private_key 現在接受 OpenSSLAsymmetricKeyOpenSSLCertificate 實例;先前接受類型為 OpenSSL keyOpenSSL X.509資源

範例

範例 #1 openssl_sign() 範例

<?php
// 假設 $data 包含要簽署的資料

// 從檔案取得私鑰並準備
$pkeyid = openssl_pkey_get_private("file://src/openssl-0.9.6/demos/sign/key.pem");

// 計算簽章
openssl_sign($data, $signature, $pkeyid);

// 從記憶體釋放密鑰
openssl_free_key($pkeyid);
?>

範例 #2 openssl_sign() 範例

<?php
// 你想要簽署的資料
$data = 'my data';

// 建立新的私鑰和公鑰
$new_key_pair = openssl_pkey_new(array(
"private_key_bits" => 2048,
"private_key_type" => OPENSSL_KEYTYPE_RSA,
));
openssl_pkey_export($new_key_pair, $private_key_pem);

$details = openssl_pkey_get_details($new_key_pair);
$public_key_pem = $details['key'];

// 建立簽章
openssl_sign($data, $signature, $private_key_pem, OPENSSL_ALGO_SHA256);

// 儲存以供稍後使用
file_put_contents('private_key.pem', $private_key_pem);
file_put_contents('public_key.pem', $public_key_pem);
file_put_contents('signature.dat', $signature);

// 驗證簽章
$r = openssl_verify($data, $signature, $public_key_pem, "sha256WithRSAEncryption");
var_dump($r);
?>

另請參閱

新增註解

使用者貢獻的註解 2 則註解

11
edmarw at yahoo dot com
17 年前
如果您只需要一個非常簡單的私鑰/公鑰對,這可能會有幫助

<?php

$data
= "Beeeeer is really good.. hic...";

// 你可以使用以下方式取得一組簡單的私鑰/公鑰對:
// openssl genrsa 512 >private_key.txt
// openssl rsa -pubout <private_key.txt >public_key.txt

// 重要:以下金鑰對僅供測試使用。
// 顯然地,基於安全考量,您必須取得新的金鑰對
// 供正式環境使用。

$private_key = <<<EOD
-----BEGIN RSA PRIVATE KEY-----
MIIBOgIBAAJBANDiE2+Xi/WnO+s120NiiJhNyIButVu6zxqlVzz0wy2j4kQVUC4Z
RZD80IY+4wIiX2YxKBZKGnd2TtPkcJ/ljkUCAwEAAQJAL151ZeMKHEU2c1qdRKS9
sTxCcc2pVwoAGVzRccNX16tfmCf8FjxuM3WmLdsPxYoHrwb1LFNxiNk1MXrxjH3R
6QIhAPB7edmcjH4bhMaJBztcbNE1VRCEi/bisAwiPPMq9/2nAiEA3lyc5+f6DEIJ
h1y6BWkdVULDSM+jpi1XiV/DevxuijMCIQCAEPGqHsF+4v7Jj+3HAgh9PU6otj2n
Y79nJtCYmvhoHwIgNDePaS4inApN7omp7WdXyhPZhBmulnGDYvEoGJN66d0CIHra
I2SvDkQ5CmrzkW5qPaE2oO7BSqAhRZxiYpZFb5CI
-----END RSA PRIVATE KEY-----
EOD;
$public_key = <<<EOD
-----BEGIN PUBLIC KEY-----
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANDiE2+Xi/WnO+s120NiiJhNyIButVu6
zxqlVzz0wy2j4kQVUC4ZRZD80IY+4wIiX2YxKBZKGnd2TtPkcJ/ljkUCAwEAAQ==
-----END PUBLIC KEY-----
EOD;

$binary_signature = "";

// 至少在 PHP 5.2.2 / OpenSSL 0.9.8b (Fedora 7) 中
// 似乎不需要呼叫 openssl_get_privatekey 或類似的函式。
// 只需直接傳入上面定義的金鑰即可
openssl_sign($data, $binary_signature, $private_key, OPENSSL_ALGO_SHA1);

// 檢查簽章
$ok = openssl_verify($data, $binary_signature, $public_key, OPENSSL_ALGO_SHA1);
echo
"檢查 #1: ";
if (
$ok == 1) {
echo
"簽章正確(應為如此)\n";
} elseif (
$ok == 0) {
echo
"錯誤(發生問題)\n";
} else {
echo
"嚴重錯誤,檢查簽章時發生錯誤\n";
}

$ok = openssl_verify('tampered'.$data, $binary_signature, $public_key, OPENSSL_ALGO_SHA1);
echo
"檢查 #2: ";
if (
$ok == 1) {
echo
"錯誤:資料已被竄改,但簽章仍然有效!啊!\n";
} elseif (
$ok == 0) {
echo
"簽章錯誤(應為如此,因為資料已被竄改)\n";
} else {
echo
"嚴重錯誤,檢查簽章時發生錯誤\n";
}

?>
4
tim at remitone dot com
1 年前
需要注意的是,openssl_sign() 和 openssl_verify 預設使用的簽章演算法 (OPENSSL_ALGO_SHA1) 在 OpenSSL 3 系列版本中不再被預設支援。

若使用最新的 OpenSSL 函式庫,則必須在
函式庫所在的伺服器上執行
"update-crypto-policies --set LEGACY"
To Top