You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel/PHP转换SendGrid公钥时ECDSA验证库报错问题

解决SendGrid Webhook签名验证的gmp_init错误

问题核心

你遇到的gmp_init(): Argument #1 ($num) is not an integer string错误,本质是SendGrid提供的PEM格式公钥与ecdsa-php库PublicKey::fromString要求的格式不匹配。该方法无法直接解析PKCS#8格式的PEM公钥,需要先转换为纯Base64编码的原始公钥,或直接提取EC坐标创建公钥。

解决方案1:清理公钥格式后调用转换函数

SendGrid提供的公钥是带PEM头尾标记的PKCS#8格式,先清理掉标记和换行符,再传入转换函数:

// 原始SendGrid PEM格式公钥
$sendGridPemKey = '-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...
-----END PUBLIC KEY-----';

// 清理公钥:移除PEM头尾和所有空白字符
$cleanPublicKey = preg_replace('/-----BEGIN PUBLIC KEY-----|-----END PUBLIC KEY-----|\s+/', '', $sendGridPemKey);

// 调用SendGrid库的转换方法
$eventWebhook = new EventWebhook();
try {
    $ecPublicKey = $eventWebhook->convertPublicKeyToECDSA($cleanPublicKey);
} catch (\Exception $e) {
    var_dump($e->getMessage());
}

解决方案2:直接提取EC坐标创建公钥(更可靠)

如果方案1仍报错,可通过OpenSSL解析PEM公钥,提取EC曲线的X/Y坐标,直接用ecdsa-php的底层API创建公钥:

use StarkBank\Ecdsa\Curve;
use StarkBank\Ecdsa\Point;
use StarkBank\Ecdsa\PublicKey;
use StarkBank\Ecdsa\BigInteger;

$sendGridPemKey = '-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----';

// 用OpenSSL解析公钥
$publicKeyResource = openssl_pkey_get_public($sendGridPemKey);
$keyDetails = openssl_pkey_get_details($publicKeyResource);

// 提取EC坐标(原始二进制转十六进制字符串)
$xHex = bin2hex($keyDetails['ec']['x']);
$yHex = bin2hex($keyDetails['ec']['y']);

// 创建ECDSA公钥(SendGrid使用secp256r1曲线,即NIST P-256)
$curve = new Curve('secp256r1');
$ecPublicKey = new PublicKey(
    new Point(
        $curve,
        new BigInteger($xHex, 16),
        new BigInteger($yHex, 16)
    )
);

// 验证签名逻辑
$timestamp = $_SERVER['HTTP_X_TWILIO_EMAIL_EVENT_WEBHOOK_TIMESTAMP'];
$signature = $_SERVER['HTTP_X_TWILIO_EMAIL_EVENT_WEBHOOK_SIGNATURE'];
$requestBody = file_get_contents('php://input');

$verifyResult = $ecPublicKey->verify(
    hash('sha256', $timestamp . $requestBody, true),
    base64_decode($signature)
);

var_dump($verifyResult); // 验证成功返回true

额外检查项

  • 确保PHP已安装并启用gmp扩展(可通过phpinfo()查看)
  • 确认SendGrid公钥对应的曲线是secp256r1(NIST P-256),这是SendGrid Webhook签名的默认曲线

内容的提问来源于stack exchange,提问作者ZcomZ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 21:53:25