简体   繁体   English

C# 使用带有 SHA256 证书的 ECDSA 进行签名验证

[英]C# signature verification using ECDSA with SHA256 certificate

I'm trying to use C# and the built in Crypto libraries to verify a signature created using an EC key + SHA256.我正在尝试使用 C# 和内置的 Crypto 库来验证使用 EC 密钥 + SHA256 创建的签名。 Here's what I'm doing.这就是我正在做的事情。

I've created a private key and corresponding certificate using openssl:我使用 openssl 创建了一个私钥和相应的证书:

$ openssl ecparam -genkey -name prime256v1 -out ca.key
$ openssl req -x509 -new -SHA256 -nodes -key ca.key -days 36500 -out ca.crt

Here are the keys I'm using (don't worry, they're not important):这是我正在使用的键(别担心,它们并不重要):

$ cat ca.key 
-----BEGIN EC PARAMETERS-----
BggqhkjOPQMBBw==
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIHd3OvRV1nEnoDxGzzemX1x8l2rHasWH3L/LflUGg5vloAoGCCqGSM49
AwEHoUQDQgAE7f1xwQL5m/UcN4zL+zsly6V1g3/wNcL5TdCfWt0XfnUfg0x+RsIf
1uerBnhrmhH0cN9o0xfXg5B3hURFlXVuEQ==
-----END EC PRIVATE KEY-----

$ cat ca.crt 
-----BEGIN CERTIFICATE-----
MIIB4TCCAYegAwIBAgIUKt0WdaKI2eRXBO2nVk+OF6AZqHMwCgYIKoZIzj0EAwIw
RTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGElu
dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAgFw0yMDA1MDcxMzM2MTNaGA8yMTIwMDQx
MzEzMzYxM1owRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAf
BgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDBZMBMGByqGSM49AgEGCCqG
SM49AwEHA0IABO39ccEC+Zv1HDeMy/s7JculdYN/8DXC+U3Qn1rdF351H4NMfkbC
H9bnqwZ4a5oR9HDfaNMX14OQd4VERZV1bhGjUzBRMB0GA1UdDgQWBBRGuUmsyB2h
JCXMRTVMRTcdoWZQaDAfBgNVHSMEGDAWgBRGuUmsyB2hJCXMRTVMRTcdoWZQaDAP
BgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMCA0gAMEUCIGG8tQZlh7aJaI34Y7jq
44SmSc/ule9MgjIX+Gg+i5vwAiEA9Jb/304KO4t9OMqFMQeWZXIHdzhDFBwx7FWz
78+UsnY=
-----END CERTIFICATE-----

I then have a simple data file containing the string "Hello".然后我有一个包含字符串“Hello”的简单数据文件。 I then sign that file using openssl as follows:然后我使用 openssl 签署该文件,如下所示:

$ openssl dgst -sha256 -sign ca.key data.txt > sig
$ base64 sig 
MEUCIQD5593C/NBhHA1DILT72gjhGj/lKjom9vYP+JbuypBrxQIgNAjYT1LihEpPbUhe1n9ccUHQ
vw676bGqOTEU/25qcRQ=

I can then verify the signature by first extracting the public key from the certificate and then using that to verify:然后我可以通过首先从证书中提取公钥然后使用它来验证签名来验证签名:

$ openssl x509 -pubkey -noout -in ca.crt > ca.pub
$ cat ca.pub 
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE7f1xwQL5m/UcN4zL+zsly6V1g3/w
NcL5TdCfWt0XfnUfg0x+RsIf1uerBnhrmhH0cN9o0xfXg5B3hURFlXVuEQ==
-----END PUBLIC KEY-----
$ openssl dgst -verify ca.pub -sha256 -signature sig data.txt 
Verified OK

I then try and use C# (.NET Core 3.1) to verify the signature.然后我尝试使用 C# (.NET Core 3.1) 来验证签名。 The code is as follows:代码如下:

using System;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;

namespace security_sandbox
{
    class Program
    {
        static void Main(string[] args)
        {
            var certData = Encoding.ASCII.GetBytes(
                @"-----BEGIN CERTIFICATE-----
MIIB4TCCAYegAwIBAgIUKt0WdaKI2eRXBO2nVk+OF6AZqHMwCgYIKoZIzj0EAwIw
RTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGElu
dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAgFw0yMDA1MDcxMzM2MTNaGA8yMTIwMDQx
MzEzMzYxM1owRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAf
BgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDBZMBMGByqGSM49AgEGCCqG
SM49AwEHA0IABO39ccEC+Zv1HDeMy/s7JculdYN/8DXC+U3Qn1rdF351H4NMfkbC
H9bnqwZ4a5oR9HDfaNMX14OQd4VERZV1bhGjUzBRMB0GA1UdDgQWBBRGuUmsyB2h
JCXMRTVMRTcdoWZQaDAfBgNVHSMEGDAWgBRGuUmsyB2hJCXMRTVMRTcdoWZQaDAP
BgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMCA0gAMEUCIGG8tQZlh7aJaI34Y7jq
44SmSc/ule9MgjIX+Gg+i5vwAiEA9Jb/304KO4t9OMqFMQeWZXIHdzhDFBwx7FWz
78+UsnY=
-----END CERTIFICATE-----");

            var cert = new X509Certificate2(certData);
            var ecdsa = cert.GetECDsaPublicKey();

            var data = Encoding.ASCII.GetBytes("Hello");
            var signature = Convert.FromBase64String("MEUCIQD5593C/NBhHA1DILT72gjhGj/lKjom9vYP+JbuypBrxQIgNAjYT1LihEpPbUhe1n9ccUHQvw676bGqOTEU/25qcRQ=");

            var success = ecdsa.VerifyData(data, signature, HashAlgorithmName.SHA256);

            if (success)
            {
                Console.WriteLine("Verified");
            } else
            {
                Console.WriteLine("Failed");
            }
        }
    }
}

Unfortunately, it always fails the verification.不幸的是,它总是无法通过验证。 Where is the mistake?错误在哪里?

The lack of PEM/OpenSSL-compatible manipulation tools in .NET proved to be extremely frustrating. .NET 中缺乏与 PEM/OpenSSL 兼容的操作工具被证明是非常令人沮丧的。 I ended up using Bouncy Castle to load the certificate or public key and then use that to verify my ASN signature.我最终使用Bouncy Castle加载证书或公钥,然后使用它来验证我的 ASN 签名。 Here's a full working code sample demonstrating how to perform the signature verification using both the certificate and the PEM public key and working with an ASN-encoded signature.这是一个完整的工作代码示例,演示了如何使用证书和 PEM 公钥以及使用 ASN 编码的签名来执行签名验证。

using System;
using System.IO;
using System.Text;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.OpenSsl;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.X509;

namespace security_sandbox
{
    class Program
    {
        static void Main(string[] args)
        {

            var certificateString =  @"-----BEGIN CERTIFICATE-----
MIIB4TCCAYegAwIBAgIUKt0WdaKI2eRXBO2nVk+OF6AZqHMwCgYIKoZIzj0EAwIw
RTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGElu
dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAgFw0yMDA1MDcxMzM2MTNaGA8yMTIwMDQx
MzEzMzYxM1owRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAf
BgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDBZMBMGByqGSM49AgEGCCqG
SM49AwEHA0IABO39ccEC+Zv1HDeMy/s7JculdYN/8DXC+U3Qn1rdF351H4NMfkbC
H9bnqwZ4a5oR9HDfaNMX14OQd4VERZV1bhGjUzBRMB0GA1UdDgQWBBRGuUmsyB2h
JCXMRTVMRTcdoWZQaDAfBgNVHSMEGDAWgBRGuUmsyB2hJCXMRTVMRTcdoWZQaDAP
BgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMCA0gAMEUCIGG8tQZlh7aJaI34Y7jq
44SmSc/ule9MgjIX+Gg+i5vwAiEA9Jb/304KO4t9OMqFMQeWZXIHdzhDFBwx7FWz
78+UsnY=
-----END CERTIFICATE-----";
            var pemreader = new PemReader(new StringReader(certificateString));
            var cert = (X509Certificate)pemreader.ReadObject();

            // Alternatively, load the public key directly
            var pubkeyString = 
@"-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE7f1xwQL5m/UcN4zL+zsly6V1g3/w
NcL5TdCfWt0XfnUfg0x+RsIf1uerBnhrmhH0cN9o0xfXg5B3hURFlXVuEQ==
-----END PUBLIC KEY-----";
            pemreader = new PemReader(new StringReader(pubkeyString));
            var pubkey = (AsymmetricKeyParameter)pemreader.ReadObject();

            var data = "Hello";
            var signature = Convert.FromBase64String("MEUCIQD5593C/NBhHA1DILT72gjhGj/lKjom9vYP+JbuypBrxQIgNAjYT1LihEpPbUhe1n9ccUHQvw676bGqOTEU/25qcRQ=");

            // Verify using the public key
            var signer = SignerUtilities.GetSigner("SHA-256withECDSA");
            signer.Init(false, pubkey);
            signer.BlockUpdate(Encoding.ASCII.GetBytes(data), 0, data.Length);
            var success = signer.VerifySignature(signature);

            if (success) {
                Console.WriteLine("Signature verified successfully using public key");
            } else {
                Console.WriteLine("Failed to verify signature using public key");
            }

            // Verify using the certificate - the certificate's public key is extracted using the GetPublicKey method.
            signer.Init(false, cert.GetPublicKey());
            signer.BlockUpdate(Encoding.ASCII.GetBytes(data), 0, data.Length);
            success = signer.VerifySignature(signature);

            if (success) {
                Console.WriteLine("Signature verified successfully using certificate");
            } else {
                Console.WriteLine("Failed to verify signature using certificate");
            }
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用BouncyCastle进行数字签名验证 - 带有SHA 256,C#的ECDSA - Digital Signature Verification using BouncyCastle - ECDSA with SHA 256, C# 如何在 C# 中使用 SHA256 签名对 ECDSA 进行签名和验证 - How to sign and verify an ECDSA with SHA256 signature in C# 如何在C#中使用带有ECDSA算法的SHA256创建数字签名 - How to create a digital signature using SHA256 with ECDSA algorithm in C# 使用BouncyCastle验证在C#中用ECDSA(带有SHA256)签名的XMLSignature抛出InvalidCastException - Verifying XMLSignature signed with ECDSA (with SHA256) in C# using BouncyCastle throws InvalidCastException SSO SAML的签名XML签名验证(使用sha256) - Signed XML signature verification for SSO SAML (Using sha256) 使用SoftHSM 2.2.0(带有SHA256的ECDSA)C#.net从Pkcs11Interop为CKM_ECDSA_SHA256签名PDF - Signing PDF from Pkcs11Interop for CKM_ECDSA_SHA256 using SoftHSM 2.2.0 (ECDSA with SHA256) C# .net 验证 C# 中的 RSA SHA256 签名 - Verify RSA SHA256 signature in C# Bouncy Castle 使用 C# 签署和验证 SHA256 证书 - Bouncy Castle Sign and Verify SHA256 Certificate With C# Binance API HMAC SHA256 签名错误 使用 C# - Binance API HMAC SHA256 Signature error Using C# 使用SHA256的PayFort签名 - PayFort Signature using SHA256
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM