切换主题
Php 签名 & 验签 示例
在 API 请求中,为了确保数据的完整性和安全性,我们使用 RSA 签名 机制来对请求进行加密签名,并在接收方进行验签。
本示例提供了一个 SignatureHandler 类,用于 生成签名 和 验证签名
php
<?php
namespace Sign;
class SignatureHandler
{
private $key;
private $is_private;
public function __construct(string $key, string $key_type = 'private')
{
// 初始化签名/验签类
if ($key_type == 'private') {
// 生成私钥
$pem_key = "-----BEGIN PRIVATE KEY-----\n" . wordwrap($key, 64, "\n", true) . "\n-----END PRIVATE KEY-----";
$this->key = openssl_pkey_get_private($pem_key);
$this->is_private = true;
} elseif ($key_type == 'public') {
// 生成公钥
$pem_key = "-----BEGIN PUBLIC KEY-----\n" . wordwrap($key, 64, "\n", true) . "\n-----END PUBLIC KEY-----";
$this->key = openssl_pkey_get_public($pem_key);
$this->is_private = false;
} else {
throw new Exception("Invalid key_type. Must be 'private' or 'public'.");
}
}
public function generate_signature(string $merchant_id, string $timestamp, string $timezone, array $body): string
{
if (!$this->is_private) {
throw new Exception("Key must be private to generate signature.");
}
// 拼接签名内容
$body_str = json_encode($body, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
$sign_content = "$merchant_id.$timestamp.$timezone.$body_str";
// 生成签名
$signature = null;
openssl_sign($sign_content, $signature, $this->key, OPENSSL_ALGO_SHA256);
// 返回 Base64 编码的签名字符串
return base64_encode($signature);
}
public function verify_signature(string $merchant_id, string $timestamp, string $timezone, array $body, string $received_signature): bool
{
if ($this->is_private) {
throw new Exception("Key must be public to verify signature.");
}
// 拼接签名内容
$body_str = json_encode($body, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
$sign_content = "$merchant_id.$timestamp.$timezone.$body_str";
// 解码收到的签名
$decoded_signature = base64_decode($received_signature);
// 验证签名
$result = openssl_verify($sign_content, $decoded_signature, $this->key, OPENSSL_ALGO_SHA256);
// 如果验证成功,返回 true,否则返回 false
return $result === 1;
}
}