C# 验证签名

发布于 2024-11-05 07:28:57 字数 4339 浏览 1 评论 0原文

我有以下代码在发送数据之前对我的数据进行签名(http):

    internal static byte[] Encode(byte[] arMessage, string signerCert, string signerPassword)
            {
                X509Certificate2 cert = new X509Certificate2(signerCert, signerPassword);
                //debug data
                var msg = System.Text.ASCIIEncoding.ASCII.GetString(arMessage);
                //--
                ContentInfo contentInfo = new ContentInfo(arMessage);

                SignedCms signedCms = new SignedCms(contentInfo, true); // <- true detaches the signature
                CmsSigner cmsSigner = new CmsSigner(cert);

                signedCms.ComputeSignature(cmsSigner);
                byte[] signature = signedCms.Encode();

                return signature;
            }

执行以下操作后我可以看到签名:

    string sig = Convert.ToBase64String(bSignature) + MESSAGE_SEPARATOR;
    //this will be included in the message:
    bSignature = System.Text.ASCIIEncoding.ASCII.GetBytes(sig);

    //debug data, see the signature:
    string deb8 = System.Text.ASCIIEncoding.ASCII.GetString(bSignature);
    //--

例如:

MIICvgYJKoZIhvcNAQcCoIICrzCCAqsCAQExCzAJBgUrDgMCGgUAMAsGCSqGSIb3DQEHAaCCAbgwggG0MIIBXqADAgECAhAGicJ2MhB7tUZtG3QcdWDwMA0GCSqGSIb3DQEBBAUAMBYxFDASBgNVBAMTC1Jvb3QgQWdlbmN5MB4XDTExMDUwMzEyMTQ0NVoXDTM5MTIzMTIzNTk1OVowDzENMAsGA1UEAxMEVGVzdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAuOm4jGHUzLPNww6sx7cZJJxjLIDL/rVVLOtDd1NeA4DZZM1+lKwLpDp3FrV1CA4NP7g3weTg6Y0Jb6X7CSQHnfHRzU8LLrHgp/D9NJ39/RhsKggUteMa1FUUas0fMDMELtTO07ejNfYAhDYQiXmeg+pIMpUfeUhMicyV2xrPzG8CAwEAAaNLMEkwRwYDVR0BBEAwPoAQEuQJLQYdHU8AjWEh3BZkY6EYMBYxFDASBgNVBAMTC1Jvb3QgQWdlbmN5ghAGN2wAqgBkihHPuNSqXDX0MA0GCSqGSIb3DQEBBAUAA0EAVIjI0My490lY6vKrcgorZZ8MBo3MSk9HuDRBE0SRwSQjnvPsAD0ol1ZjvzjFKA/0Vgvp1lyYquCTSL8R/uWf+TGBzzCBzAIBATAqMBYxFDASBgNVBAMTC1Jvb3QgQWdlbmN5AhAGicJ2MhB7tUZtG3QcdWDwMAkGBSsOAwIaBQAwDQYJKoZIhvcNAQEBBQAEgYCuXG2CJ0G6UaO1AVMpo5ul3JkJ9EvJbdwb6sXOqOonq5qKbaGJsx0sgwoBfg3lLMP3UI9JVi4dTGG4KTzA1k/0Qt0owmEPKrDh3zVZr2hK/iHsW75sGjSgYT4hxbn6ziQ2IFoN2qCbxdXrMZ+TD0pf7o/ABdorjlvQ5USwlPKjZQ==

这是我在收到的消息中的内容。 所以问题是:如何验证接收者收到的消息的签名(是否提供了 .cer 文件)? 提前致谢

编辑 1:

我尝试遵循 Daniel Hilgarth 的逻辑,但没有成功。 有几次我遇到了“ASN Bad tag value”异常。 为了方便起见,我对用于生成签名的消息进行了硬编码 因此,在接收器上我有两件事:原始消息和为其生成的签名:

    //Signature from the message  (string in ASCII)
    var signatureKey = GetSignatureFromSignatureMessage(signatureMessage, boundary);
    //Original sent message (the arMessage itself used in Encode method above, converted to string from byte) 
    var messageOriginal =
        "Content-Type: application/EDIFACT\r\nContent-Transfer-Encoding: binary\r\n\r\nSome short text.\r\nVery short.";

我需要检查签名是否对应于该消息。 所以我尝试做这样的事情:

//contentInfo from the original message.
ContentInfo contentInfo = new ContentInfo(System.Text.ASCIIEncoding.ASCII.GetBytes(messageOriginal));

//SingedCms from the contentInfo above
SignedCms signedCms = new SignedCms(contentInfo, true);

//Here, I believe, I am attaching the signature I have to the Cms    
 signedCms.Decode(System.Text.ASCIIEncoding.ASCII.GetBytes(signatureKey));

//checking?
signedCms.CheckSignature(true);

并且我在解码部分遇到异常。

有什么建议吗?

编辑2: 解决方案: 丹尼尔·希尔加斯给出的方向是正确的。 我的问题是发送者对密钥进行了几次编码: Base64 字节数组 -> Base64String ->; ASCII 字节数组 -> ASCII 字符串 ->发送消息 接收器已经接收到 ASCII 格式的数据,执行以下操作: ASCII 字符串 ->字节数组。 我必须将所有内容转换回 Base64 字节数组才能使其正常工作。

    //Signature from the message (ASCII String)
    var signatureKey = GetSignatureFromSignatureMessage(signatureMessage, boundary);

    //Original Byte Array (Base64)
    var sigKeyBase = Convert.FromBase64String(signatureKey);

   //Original sent message
    var messageOriginal =
        "Content-Type: application/EDIFACT\r\nContent-Transfer-Encoding: binary\r\n\r\nSome short text.\r\nVery short.";

    var messageOriginalByteASCII = System.Text.ASCIIEncoding.ASCII.GetBytes(messageOriginal);


    ContentInfo contentInfo = new ContentInfo(messageOriginalByteASCII);
    SignedCms signedCms = new SignedCms(contentInfo, true);
    signedCms.Decode(sigKeyBase);

    signedCms.CheckSignature(true);

在这种情况下它通过了检查。 PS 太糟糕了 ChekSignature 不返回 true 或 false。恕我直言,我会更舒服。 :(

I have the following code to sign my data before sending it (http):

    internal static byte[] Encode(byte[] arMessage, string signerCert, string signerPassword)
            {
                X509Certificate2 cert = new X509Certificate2(signerCert, signerPassword);
                //debug data
                var msg = System.Text.ASCIIEncoding.ASCII.GetString(arMessage);
                //--
                ContentInfo contentInfo = new ContentInfo(arMessage);

                SignedCms signedCms = new SignedCms(contentInfo, true); // <- true detaches the signature
                CmsSigner cmsSigner = new CmsSigner(cert);

                signedCms.ComputeSignature(cmsSigner);
                byte[] signature = signedCms.Encode();

                return signature;
            }

I can see the signature after doing the following:

    string sig = Convert.ToBase64String(bSignature) + MESSAGE_SEPARATOR;
    //this will be included in the message:
    bSignature = System.Text.ASCIIEncoding.ASCII.GetBytes(sig);

    //debug data, see the signature:
    string deb8 = System.Text.ASCIIEncoding.ASCII.GetString(bSignature);
    //--

For example:

MIICvgYJKoZIhvcNAQcCoIICrzCCAqsCAQExCzAJBgUrDgMCGgUAMAsGCSqGSIb3DQEHAaCCAbgwggG0MIIBXqADAgECAhAGicJ2MhB7tUZtG3QcdWDwMA0GCSqGSIb3DQEBBAUAMBYxFDASBgNVBAMTC1Jvb3QgQWdlbmN5MB4XDTExMDUwMzEyMTQ0NVoXDTM5MTIzMTIzNTk1OVowDzENMAsGA1UEAxMEVGVzdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAuOm4jGHUzLPNww6sx7cZJJxjLIDL/rVVLOtDd1NeA4DZZM1+lKwLpDp3FrV1CA4NP7g3weTg6Y0Jb6X7CSQHnfHRzU8LLrHgp/D9NJ39/RhsKggUteMa1FUUas0fMDMELtTO07ejNfYAhDYQiXmeg+pIMpUfeUhMicyV2xrPzG8CAwEAAaNLMEkwRwYDVR0BBEAwPoAQEuQJLQYdHU8AjWEh3BZkY6EYMBYxFDASBgNVBAMTC1Jvb3QgQWdlbmN5ghAGN2wAqgBkihHPuNSqXDX0MA0GCSqGSIb3DQEBBAUAA0EAVIjI0My490lY6vKrcgorZZ8MBo3MSk9HuDRBE0SRwSQjnvPsAD0ol1ZjvzjFKA/0Vgvp1lyYquCTSL8R/uWf+TGBzzCBzAIBATAqMBYxFDASBgNVBAMTC1Jvb3QgQWdlbmN5AhAGicJ2MhB7tUZtG3QcdWDwMAkGBSsOAwIaBQAwDQYJKoZIhvcNAQEBBQAEgYCuXG2CJ0G6UaO1AVMpo5ul3JkJ9EvJbdwb6sXOqOonq5qKbaGJsx0sgwoBfg3lLMP3UI9JVi4dTGG4KTzA1k/0Qt0owmEPKrDh3zVZr2hK/iHsW75sGjSgYT4hxbn6ziQ2IFoN2qCbxdXrMZ+TD0pf7o/ABdorjlvQ5USwlPKjZQ==

This is what I have in the received message.
So the question is: how to validate the signature of the received message on the recipient (has the .cer file provided)?
Thanks in advance

Edit 1:

I tried to follow the Daniel Hilgarth's logic but it didn't worked.
A few times I met the "ASN Bad tag value" exception.
To make it easier, I hardcoded the message being used to generate the signature
So, on the receiver I have 2 things: the original message and the signature generated for it:

    //Signature from the message  (string in ASCII)
    var signatureKey = GetSignatureFromSignatureMessage(signatureMessage, boundary);
    //Original sent message (the arMessage itself used in Encode method above, converted to string from byte) 
    var messageOriginal =
        "Content-Type: application/EDIFACT\r\nContent-Transfer-Encoding: binary\r\n\r\nSome short text.\r\nVery short.";

I need to check if the signature corresponds this message.
So I am trying to do something like this:

//contentInfo from the original message.
ContentInfo contentInfo = new ContentInfo(System.Text.ASCIIEncoding.ASCII.GetBytes(messageOriginal));

//SingedCms from the contentInfo above
SignedCms signedCms = new SignedCms(contentInfo, true);

//Here, I believe, I am attaching the signature I have to the Cms    
 signedCms.Decode(System.Text.ASCIIEncoding.ASCII.GetBytes(signatureKey));

//checking?
signedCms.CheckSignature(true);

And I get exceptions on decode part.

Any advices?

Edit 2:
Solution:
The direction given by Daniel Hilgarth is right.
My problem was that the sender encoded the key few times:
Base64 byte array -> Base64String -> ASCII byte array -> ASCII string -> Send_message
The receiver was receiving the data in ASCII already, doing:
ASCII String -> Byte array.
I had to convert everything back to base64 byte array to make it work.

    //Signature from the message (ASCII String)
    var signatureKey = GetSignatureFromSignatureMessage(signatureMessage, boundary);

    //Original Byte Array (Base64)
    var sigKeyBase = Convert.FromBase64String(signatureKey);

   //Original sent message
    var messageOriginal =
        "Content-Type: application/EDIFACT\r\nContent-Transfer-Encoding: binary\r\n\r\nSome short text.\r\nVery short.";

    var messageOriginalByteASCII = System.Text.ASCIIEncoding.ASCII.GetBytes(messageOriginal);


    ContentInfo contentInfo = new ContentInfo(messageOriginalByteASCII);
    SignedCms signedCms = new SignedCms(contentInfo, true);
    signedCms.Decode(sigKeyBase);

    signedCms.CheckSignature(true);

In this case it passes Check.
P.S. Too bad ChekSignature doesn't return true or false. I'd be more comfortable imho. :(

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

享受孤独 2024-11-12 07:28:57

嗯...也许使用 SignedCms.CheckSignature?!与 SignedCms 结合使用.解码。基本上,只需使用与签署文档相反的方式即可。 MSDN 页面提供了带有分离签名的示例:

// Create a ContentInfo object from the inner content obtained 
// independently from encodedMessage.
ContentInfo contentInfo = new ContentInfo(innerContent);

// Create a new, detached SignedCms message.
SignedCms signedCms = new SignedCms(contentInfo, true);

// encodedMessage is the encoded message received from 
// the sender.
signedCms.Decode(encodedMessage);

// Verify the signature without validating the 
// certificate.
signedCms.CheckSignature(true);

Hm... maybe using SignedCms.CheckSignature?! Use it in conjunction with SignedCms.Decode. Basically, just use the reverse way you use to sign the document. An example with detached signature is available from the MSDN page:

// Create a ContentInfo object from the inner content obtained 
// independently from encodedMessage.
ContentInfo contentInfo = new ContentInfo(innerContent);

// Create a new, detached SignedCms message.
SignedCms signedCms = new SignedCms(contentInfo, true);

// encodedMessage is the encoded message received from 
// the sender.
signedCms.Decode(encodedMessage);

// Verify the signature without validating the 
// certificate.
signedCms.CheckSignature(true);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文