【问题标题】:Rsa Signature Header VerificationRsa 签名标头验证
【发布时间】:2022-01-05 07:08:18
【问题描述】:

我正在测试签名验证: https://datatracker.ietf.org/doc/html/draft-cavage-http-signatures-07#appendix-C

我从示例中获取了公钥并使用标头验证签名 这是我在 C# 中的代码

     public async Task<string> VerifyTest()
    {


        SigningString += "(request-target): post/foo?param=value&pet=dog" + "\n";
        SigningString += "host: example.com\n";
        SigningString += "date: Thu, 05 Jan 2014 21:31:40 GMT\n";
        SigningString += "content-type: application/json\n";
        SigningString += "digest: SHA-256=X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE=\n";
        SigningString += "content-length: 18";

        string Signature = @"jgSqYK0yKclIHfF9zdApVEbDp5eqj8C4i4X76pE+XHoxugXv7qnVrGR+30bmBgtpR39I4utq17s9ghz/2QFVxlnToYAvbSVZJ9ulLd1HQBugO0jOyn9sXOtcN7uNHBjqNCqUsnt0sw/cJA6B6nJZpyNqNyAXKdxZZItOuhIs78w=";


        string ClientPublicKey = @"-----BEGIN PUBLIC KEY-----MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCFENGw33yGihy92pDjZQhl0C36rPJj+CvfSC8+q28hxA161QFNUd13wuCTUcq0Qd2qsBe/2hFyc2DCJJg0h1L78+6Z4UMR7EOcpfdUE9Hf3m/hs+FUR45uBJeDK1HSFHD8bHKD6kv8FPGfJTotc+2xjJwoYi+1hqp1fIekaxsyQIDAQAB-----END PUBLIC KEY-----";



        string x509Pem = ClientPublicKey;

        byte[] message = Encoding.UTF8.GetBytes(SigningString);
        byte[] signature = Convert.FromBase64String(Signature);

        byte[] Sha256Message = SHA256.Create().ComputeHash(message);
        string x = Convert.ToBase64String(Sha256Message);


        PemReader pr = new PemReader(new StringReader(x509Pem));
        AsymmetricKeyParameter publicKey = (AsymmetricKeyParameter)pr.ReadObject();

        RSAParameters rsaParams = DotNetUtilities.ToRSAParameters((RsaKeyParameters)publicKey);
        RSACng rsaCng = new RSACng();
        rsaCng.ImportParameters(rsaParams);

        var boolHash = rsaCng.VerifyHash(Sha256Message, signature, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);



        return boolHash.ToString();
    }

我哪里做错了?

编辑

我想验证 http 请求的标头。请求具有授权标头,该标头具有请求的签名。请求标头取自:

https://datatracker.ietf.org/doc/html/draft-cavage-http-signatures-07#appendix-C.3

这是请求标头:

   (request-target): post /foo?param=value&pet=dog
   host: example.com
   date: Thu, 05 Jan 2014 21:31:40 GMT
   content-type: application/json
   digest: SHA-256=X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE=
   content-length: 18

这是请求中的授权标头:

Authorization: Signature keyId="Test",algorithm="rsa-sha256",
headers="(request-target) host date content-type digest content-length",
signature="jgSqYK0yKclIHfF9zdApVEbDp5eqj8C4i4X76pE+XHoxugXv7q
nVrGR+30bmBgtpR39I4utq17s9ghz/2QFVxlnToYAvbSVZJ9ulLd1HQBugO0j
Oyn9sXOtcN7uNHBjqNCqUsnt0sw/cJA6B6nJZpyNqNyAXKdxZZItOuhIs78w="

授权头中的签名字段是带有rsa私钥的请求头的base64加密字符串。

我想使用客户端公钥验证请求标头。钥匙位于那里: https://datatracker.ietf.org/doc/html/draft-cavage-http-signatures-07#appendix-C

但是签名不匹配。任何帮助都会很棒。谢谢。

【问题讨论】:

  • 似乎是什么问题?你没有指定它。
  • 例如在 C.3 部分:datatracker.ietf.org/doc/html/… i 给了我们签名字符串。当我使用给定的 rsa 公钥(在此处给出:datatracker.ietf.org/doc/html/…)加密签名字符串时,我无法达到标头包含的签名。当我验证它不匹配的哈希时。一切都正确,但我找不到问题。

标签: .net .net-core encryption cryptography rsa


【解决方案1】:

使用的参考是 2017 年 7 月的草稿 (draft-cavage-http-signatures-07)。测试数据似乎是错误的!

2019 年 10 月有更新的草稿 (draft-cavage-http-signatures-12)。那里使用的值可以验证成功。

两个草稿使用相同的密钥。不同之处在于日期部分和签名。

下面的代码演示了使用 draft-cavage-http-signatures-12 中的数据验证成功以及使用 draft-cavage-http-signatures-07 中的数据验证失败

string x509Pem = @"-----BEGIN PUBLIC KEY-----
                   MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCFENGw33yGihy92pDjZQhl0C3
                   6rPJj+CvfSC8+q28hxA161QFNUd13wuCTUcq0Qd2qsBe/2hFyc2DCJJg0h1L78+6
                   Z4UMR7EOcpfdUE9Hf3m/hs+FUR45uBJeDK1HSFHD8bHKD6kv8FPGfJTotc+2xjJw
                   oYi+1hqp1fIekaxsyQIDAQAB
                   -----END PUBLIC KEY-----";

// Verification draft 12: succeeds
string messageStr = "(request-target): post /foo?param=value&pet=dog\n"
                      + "host: example.com\n"
                      + "date: Sun, 05 Jan 2014 21:31:40 GMT\n"
                      + "content-type: application/json\n"
                      + "digest: SHA-256=X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE=\n"
                      + "content-length: 18";
string signatureB64 = "vSdrb+dS3EceC9bcwHSo4MlyKS59iFIrhgYkz8+oVLEEzmYZZvRs8rgOp+63LEM3v+MFHB32NfpB2bEKBIvB1q52LaEUHFv120V01IL+TAD48XaERZFukWgHoBTLMhYS2Gb51gWxpeIq8knRmPnYePbF5MOkR0Zkly4zKH7s1dE=";
Console.WriteLine(VerifyTest(messageStr, signatureB64, x509Pem)); // True

// Verification draft 7: fails
messageStr = "(request-target): post /foo?param=value&pet=dog\n"
              + "host: example.com\n"
              + "date: Thu, 05 Jan 2014 21:31:40 GMT\n"
              + "content-type: application/json\n"
              + "digest: SHA-256=X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE=\n"
              + "content-length: 18";
signatureB64 = "jgSqYK0yKclIHfF9zdApVEbDp5eqj8C4i4X76pE+XHoxugXv7qnVrGR+30bmBgtpR39I4utq17s9ghz/2QFVxlnToYAvbSVZJ9ulLd1HQBugO0jOyn9sXOtcN7uNHBjqNCqUsnt0sw/cJA6B6nJZpyNqNyAXKdxZZItOuhIs78w=";
Console.WriteLine(VerifyTest(messageStr, signatureB64, x509Pem)); // False

与您稍作修改的VerifyTest():

public static bool VerifyTest(string messageStr, string signatureB64, string x509Pem)
{
    byte[] message = Encoding.UTF8.GetBytes(messageStr);
    byte[] signature = Convert.FromBase64String(signatureB64);
    byte[] sha256Message = SHA256.Create().ComputeHash(message);

    PemReader pr = new PemReader(new StringReader(x509Pem));
    AsymmetricKeyParameter publicKey = (AsymmetricKeyParameter)pr.ReadObject();

    RSAParameters rsaParams = DotNetUtilities.ToRSAParameters((RsaKeyParameters)publicKey);
    RSACng rsaCng = new RSACng();
    rsaCng.ImportParameters(rsaParams);
    var verified = rsaCng.VerifyHash(sha256Message, signature, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);

    return verified;
}

【讨论】:

  • 你拯救了我们的日子 Topaco。你很棒!我不认为测试数据可能是错误的。太奇怪了。非常感谢。
猜你喜欢
  • 2016-01-15
  • 2019-11-24
  • 1970-01-01
  • 2012-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-06
  • 1970-01-01
相关资源
最近更新 更多