php使用hash_hmac签名及验签
发布日期: 2024-03-22
FontSize: 【小 中 大】

签名和验签一般用于校验数据完整性和身份认证,确保数据在传输过程中没有被篡改或伪造。签名与验签的方式有很多种,使用hash_hmac签名及验签只是其中一种。
php函数hash_hmac用于计算散列消息认证码(HMAC)。HMAC 是一种基于哈希函数的消息认证算法,它可以确保数据在传输过程中没有被篡改。hash_hmac() 函数需要三个参数:哈希算法、要加密的数据和密钥。
语法:
hash_hmac ( string $algo , string $data , string $key [, bool $raw_output = false ] )
参数说明:
- $algo:用于计算散列的哈希算法。可以是md5、sha1、sha256 等。
- $data:要加密的数据。
- $key:用于计算 HMAC 的密钥。
- $raw_output:可选参数,默认为 false。如果设置为 true,则返回原始二进制格式的哈希值;如果设置为 false,则返回十六进制编码的哈希值。
在线示例:
<?php
print_r('<pre>');/*用于页面打印结果的时候更好看*/
// 签名函数
function signData($data, $secretKey) {
$signature = hash_hmac('sha256', $data, $secretKey);
return $signature;
}
// 验签函数
function verifySignature($data, $signature, $secretKey) {
$expectedSignature = hash_hmac('sha256', $data, $secretKey);
return hash_equals($expectedSignature, $signature);
}
// 示例数据
$data = "hello";
$secretKey = "world";
// 签名
$signature = signData($data, $secretKey);
echo "签名: " . $signature . "
";
// 验签
$isVerified = verifySignature($data, $signature, $secretKey);
echo "验证: " . ($isVerified ? "Passed" : "Failed") . "
";
?>
验签的原理很简单,就是将数据使用相同的方法生成签名,来校验与先前生成的签名是否一致,在传输的数据中,注意不要包含$secretKey,否则加密变得毫无意义。
为了数据的安全性,避免更容易破解$secretKey以及加密方式,一般会要求在数据中包含一个随机字符串,以及请求时间,被请求端一般会设置时间限制,例如时间有效期为1分钟。
<?php
print_r('<pre>');/*用于页面打印结果的时候更好看*/
// 签名函数
function signData($data, $secretKey) {
$signature = hash_hmac('sha256', $data, $secretKey);
return $signature;
}
// 验签函数
function verifySignature($data, $signature, $secretKey) {
$expectedSignature = hash_hmac('sha256', $data, $secretKey);
return hash_equals($expectedSignature, $signature);
}
// 示例数据
$data['str'] = "hello";
$data['nonce'] = "12345678";/*随机字符串,每次都不同*/
$data['time'] = $_SERVER['REQUEST_TIME'];/*请求日期*/
ksort($data);
$data_str = json_encode($data);
$secretKey = "world";
// 签名
$signature = signData($data_str, $secretKey);
echo "签名: " . $signature . "
";
// 验签
$isVerified = verifySignature($data_str, $signature, $secretKey);
echo "验证: " . ($isVerified ? "Passed" : "Failed") . "
";
?>
注意,如果请求的数据为数组,应该转换成字符串格式的数据。将数组进行排序ksort($data)很重要,相同内容的数组,如果排序不同,会导致验名不一样。
如果需要更为复杂与安全的签名与验签方式,推荐使用私钥对数据进行签名,使用公钥来验证签名的有效性。