<?php
function buildMessage(array $msg): string
{
if ($msg['type'] == "Notification") {
return buildNotificationMessage($msg);
} elseif (($msg['type'] == "SubscriptionConfirmation") || ($msg['type'] == "UnsubscribeConfirmation")) {
return buildSubscriptionMessage($msg);
}
return '';
}
function buildNotificationMessage(array $msg): string
{
$signMessage = "message\n" . $msg['message'] . "\n";
$signMessage .= "message_id\n" . $msg['message_id'] . "\n";
if (!empty($msg['subject'])) {
$signMessage .= "subject\n" . $msg['subject'] . "\n";
}
$signMessage .= "timestamp\n" . $msg['timestamp'] . "\n";
$signMessage .= "topic_urn\n" . $msg['topic_urn'] . "\n";
$signMessage .= "type\n" . $msg['type'] . "\n";
return $signMessage;
}
function buildSubscriptionMessage(array $msg): string
{
$signMessage = "message\n" . $msg['message'] . "\n";
$signMessage .= "message_id\n" . $msg['message_id'] . "\n";
$signMessage .= "subscribe_url\n" . $msg['subscribe_url'] . "\n";
$signMessage .= "timestamp\n" . $msg['timestamp'] . "\n";
$signMessage .= "topic_urn\n" . $msg['topic_urn'] . "\n";
$signMessage .= "type\n" . $msg['type'] . "\n";
return $signMessage;
}
function verifyMessage(array $msg, string $cert_path = ''): bool
{
$signature = base64_decode($msg['signature'] ?? '');
if (!$signature) {
return false;
}
$public_key = getCertPemContent($msg['signing_cert_url'], $cert_path);
if (!$public_key) {
return false;
}
// 生成公钥资源
$pub_key_id = openssl_pkey_get_public($public_key);
if (!$pub_key_id) {
return false;
}
// 验证签名
$result = openssl_verify(buildMessage($msg), $signature, $pub_key_id, OPENSSL_ALGO_SHA256);
if ($result == 1) {
return true;
} elseif ($result == 0) {
return false; // 签名验证失败
} else {
return false; // 验证错误
}
}
function getCertPemContent(string $signing_cert_url, string $cert_path): false|string
{
if ($cert_path) {
$file = rtrim($cert_path, '/') . '/' . basename($signing_cert_url);
if (is_file($file)) {
return file_get_contents($file);
}
}
$public_key = file_get_contents($signing_cert_url);
if ($cert_path && $public_key) {
file_put_contents($file, $public_key);
}
return $public_key;
}
var_dump(verifyMessage($data, dirname(__FILE__)));
php华为云SMN校验http(s)消息签名
最新推荐文章于 2024-04-27 15:47:22 发布