
本文旨在提供一种在 PHP/Laravel 环境下验证 Webhook 签名的方法。通过使用 openssl 扩展,我们可以对接收到的 Webhook 请求进行签名验证,确保请求的真实性和完整性。本文将详细介绍验证签名的步骤,并提供可直接使用的代码示例,帮助开发者有效地保护应用程序免受恶意请求的侵害。
在 Webhook 集成中,验证接收到的请求的签名至关重要,以确保请求来自可信的来源,并且在传输过程中没有被篡改。通常,发送方会对请求的内容进行签名,并将签名放在请求头中。接收方则需要使用相同的算法和密钥来验证签名。
以下是如何在 PHP/Laravel 中使用 openssl 扩展验证 SHA256withRSA 签名的步骤:
1. 获取签名、公钥和请求内容
立即学习“PHP免费学习笔记(深入)”;
首先,从请求头中获取签名,并获取用于验证签名的公钥。同时,获取原始的请求内容(payload),即请求体的内容。
use Illuminate\Http\Request;
public function isValid(Request $request): bool
{
$signature = $request->header('X-Signature');
if (! $signature) {
return false;
}
$publicKey = config('services.webhook.public_key'); // 从配置中获取公钥,建议不要硬编码
if (!$publicKey) {
return false;
}
$payload = $request->getContent();
// 后续步骤...
}2. 解码签名
签名通常是经过 Base64 编码的,因此需要先进行解码。
感谢您选择使用ERMEB域名授权离线网络验证系统(简称:ERMEB域名授权系统)是ERMEB团队开发,ERMEB域名授权系统是国内最稳定,最强大,最先进的域名授权管理平台解决方案之一,ERMEB域名授权系统采用PHP +Mysql的技术,ERMEB域名授权系统框架使用Thinkphp6/mysql数据库基于Markdown开发者文档开发而成,项目安装请参考ThinkPHP官方文档及下面的服务环境说
$signature = base64_decode($signature);
3. 使用 openssl_verify 函数进行验证
openssl_verify 函数用于验证签名。它接受原始数据、签名、公钥和使用的哈希算法作为参数。
$publicKey = openssl_pkey_get_public($publicKey);
$result = openssl_verify($payload, $signature, $publicKey, OPENSSL_ALGO_SHA256);
if ($result === 1) {
return true;
}
return false;
}完整示例代码:
use Illuminate\Http\Request;
class WebhookController extends Controller
{
public function handle(Request $request)
{
if ($this->isValid($request)) {
// 签名验证通过,处理 Webhook 事件
// ...
return response('Webhook received and processed successfully.', 200);
} else {
// 签名验证失败,拒绝处理
return response('Invalid signature.', 400);
}
}
private function isValid(Request $request): bool
{
$signature = $request->header('X-Signature');
if (! $signature) {
return false;
}
$publicKey = config('services.webhook.public_key'); // 从配置中获取公钥,建议不要硬编码
if (!$publicKey) {
return false;
}
$payload = $request->getContent();
$signature = base64_decode($signature);
$publicKey = openssl_pkey_get_public($publicKey);
$result = openssl_verify($payload, $signature, $publicKey, OPENSSL_ALGO_SHA256);
if ($result === 1) {
return true;
}
return false;
}
}注意事项:
- 公钥存储: 不要将公钥硬编码在代码中。建议将其存储在配置文件或环境变量中,以便于管理和更新。
- 错误处理: 检查 openssl_pkey_get_public 的返回值,确保公钥已成功加载。如果加载失败,则需要进行适当的错误处理。
- 请求内容: 确保获取到的请求内容是原始的、未经修改的。任何对请求内容的修改都会导致签名验证失败。
- 字符编码: 确保请求内容和签名都使用相同的字符编码(通常是 UTF-8)。
- 安全性: 避免使用弱哈希算法。SHA256 是一个相对安全的哈希算法,但仍然需要定期评估和更新。
- Payload的原始性: 确保$request->getContent()获取到的是未经任何处理的原始请求体。 Laravel的某些中间件可能会修改请求体,导致签名验证失败。
总结:
通过使用 openssl 扩展,可以轻松地在 PHP/Laravel 中验证 Webhook 签名。这有助于确保接收到的请求来自可信的来源,并防止恶意请求的攻击。 请务必遵循上述注意事项,以确保签名验证的正确性和安全性。










