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

.NET 4.8中C#实现JSON Webhook签名验证失败的排查与解决

JSON Webhook签名验证:.NET 4.8适配问题及解决办法

我需要验证JSON Webhook的签名,官方仅提供了JavaScript实现示例,该代码运行后控制台输出true:

const crypto = require("crypto");
const fs = require('fs');

const publicKey = fs.readFileSync('publicKey.pem', 'utf-8');
const payload = fs.readFileSync('payload.json', 'utf-8');
const signature = fs.readFileSync('signature.txt', 'utf-8');

function verify(publicKey, signature, payload) {
  const verifier = crypto.createVerify("RSA-SHA256");
  verifier.update(payload);

  return verifier.verify(
    { key: publicKey, padding: crypto.constants.RSA_PKCS1_PSS_PADDING },
    Buffer.from(signature, 'base64')
  );
}

const verified = verify(publicKey, signature, payload);

console.log('Signature Verified: ', verified);

但我在.NET 4.8环境下编写C#对应逻辑时,验证结果始终返回false,最初的实现代码如下:

private static bool VerifySignature(string publicKeyPath, string payload, string signature)
{
    byte[] byteToSign = Encoding.UTF8.GetBytes(payload);
    byte[] bsign = Convert.FromBase64String(signature);

    string pemText = File.ReadAllText(publicKeyPath);
    PemReader pr = new PemReader(new StringReader(pemText));
    AsymmetricKeyParameter publicKey = (AsymmetricKeyParameter)pr.ReadObject();
    RSAParameters rsaParams = DotNetUtilities.ToRSAParameters((RsaKeyParameters)publicKey);

    RSACryptoServiceProvider cryptoServiceProvider = new RSACryptoServiceProvider();
    cryptoServiceProvider.ImportParameters(rsaParams);

    bool result = cryptoServiceProvider.VerifyData(byteToSign, bsign, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);

    return result;
}

问题原因

JS代码使用的是RSA-PKCS1-PSS填充模式,而上述C#代码采用的是普通PKCS#1 v1.5填充(RSASignaturePadding.Pkcs1),填充算法不匹配导致验证失败。

正确的.NET 4.8实现

通过使用BouncyCastle库的PssSigner类,实现与JS一致的PSS填充签名验证,以下代码可正常运行:

private static bool VerifySignature(string publicKeyPath, string payload, string signature)
{
    byte[] byteToSign = Encoding.UTF8.GetBytes(payload);
    byte[] bsign = Convert.FromBase64String(signature);

    string pemText = File.ReadAllText(publicKeyPath);
    PemReader pr = new PemReader(new StringReader(pemText));
    AsymmetricKeyParameter publicKey = (AsymmetricKeyParameter)pr.ReadObject();

    PssSigner pssSigner = new PssSigner(new RsaEngine(), new Sha256Digest(), bsign.Length - 32 - 2);
    pssSigner.Init(false, publicKey);
    pssSigner.BlockUpdate(byteToSign, 0, byteToSign.Length);
    bool result = pssSigner.VerifySignature(bsign);

    return result;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 04:00:16