当前位置: 首页 > 知识库问答 >
问题:

如何在C#中使用SHA256签名对ECDSA进行签名和验证

白嘉石
2023-03-14

我有一个包含EC私钥的文件:

-----BEGIN EC PRIVATE KEY-----
<data>
-----END EC PRIVATE KEY-----

我有一个证书,它的公钥对应于私钥:

在 pem 格式中:

-----BEGIN CERTIFICATE-----
<data>
-----END CERTIFICATE-----

以txt格式:

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            80:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:15
        Signature Algorithm: ecdsa-with-SHA256
        Issuer: CN = MyIssuer
        Validity
            Not Before: Jan 27 19:33:43 2020 GMT
            Not After : Jun 10 19:33:43 2021 GMT
        Subject: CN = MyIssuer MyCert
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                pub:
                    04:6a:9c:40:7b:71:06:3a:7f:3a:1e:4c:5c:60:9e:
                    d0:c4:a0:c0:c7:39:ec:6d:f1:5b:27:5a:5f:3b:f8:
                    77:29:7e:38:8e:e6:77:cf:d2:9c:77:c2:43:f4:92:
                    73:a8:10:d2:e9:f2:bb:d7:4d:97:76:07:d0:1f:16:
                    7b:01:d3:35:26
                ASN1 OID: prime256v1
                NIST CURVE: P-256
        X509v3 extensions:
            X509v3 Basic Constraints: critical
                CA:FALSE
            X509v3 Authority Key Identifier: 
                keyid:E0:1C:E6:36:88:8B:3D:77:A6:9D:80:8B:7B:9B:1D:1E:FF:24:74:B3

            X509v3 Extended Key Usage: 
                TLS Web Server Authentication, TLS Web Client Authentication
            X509v3 Subject Key Identifier: 
                49:57:2F:01:37:1B:E2:B6:9C:1A:C7:A9:03:9A:D1:61:7E:9B:4A:84
            X509v3 Key Usage: critical
                Digital Signature, Non Repudiation, Key Encipherment, Data Encipherment
    Signature Algorithm: ecdsa-with-SHA256
         30:44:02:20:2c:1a:5c:ee:4a:58:59:f1:5a:4a:93:ed:e0:24:
         70:9d:15:11:5e:11:df:30:5a:0f:54:a0:9f:95:c4:eb:f9:6d:
         02:20:17:fe:e4:8c:ef:ef:34:56:fb:5d:79:40:f8:fc:f4:2f:
         97:90:4b:ac:cb:b6:64:c0:58:3e:2d:fe:7b:4f:ea:19
-----BEGIN CERTIFICATE-----
MIIBrTCCAVSgAwIBAgIVAIAAAAAAAAAAAAAAAAAAAAAAAAAVMAoGCCqGSM49BAMC
MBIxEDAOBgNVBAMMB0lzc3VlckMwHhcNMjAwMTI3MTkzMzQzWhcNMjEwNjEwMTkz
MzQzWjAaMRgwFgYDVQQDDA9Jc3N1ZXJDIERldmljZTMwWTATBgcqhkjOPQIBBggq
hkjOPQMBBwNCAARqnEB7cQY6fzoeTFxgntDEoMDHOext8VsnWl87+HcpfjiO5nfP
0px3wkP0knOoENLp8rvXTZd2B9AfFnsB0zUmo38wfTAMBgNVHRMBAf8EAjAAMB8G
A1UdIwQYMBaAFOAc5jaIiz13pp2Ai3ubHR7/JHSzMB0GA1UdJQQWMBQGCCsGAQUF
BwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQUSVcvATcb4racGsepA5rRYX6bSoQwDgYD
VR0PAQH/BAQDAgTwMAoGCCqGSM49BAMCA0cAMEQCICwaXO5KWFnxWkqT7eAkcJ0V
EV4R3zBaD1Sgn5XE6/ltAiAX/uSM7+80VvtdeUD4/PQvl5BLrMu2ZMBYPi3+e0/q
GQ==
-----END CERTIFICATE-----

我正在努力完成两件事:

    < li >使用ecdsa-with-SHA256签名算法使用私钥对字节数组进行签名 < li >使用证书中的公钥验证签名是否正确

我尝试过使用充气城堡图书馆。这是我到目前为止所拥有的。我的断言是失败的。

    [TestMethod]
    public void TestSignAndVerify()
    {

        var data = new byte[] {6, 5, 4, 3, 2};

        var keyPair = GetKeyPair();

        var signature = SignData(data, keyPair.Private);

        var valid = VerifySignature(signature, keyPair.Public);
        Assert.IsTrue(valid);

    }

    // get key pair from two local files
    private AsymmetricCipherKeyPair GetKeyPair()
    {

        AsymmetricKeyParameter privateKey, publicKey;

        var privateKeyString = File.ReadAllText("C:\\privatekey.pem");
        using (var textReader = new StringReader(privateKeyString))
        {
            // Only a private key
            var pseudoKeyPair = (AsymmetricCipherKeyPair)new PemReader(textReader).ReadObject();
            privateKey = pseudoKeyPair.Private;
        }

        var certificateString = File.ReadAllText("C:\\publicCert.pem");
        using (var textReader = new StringReader(certificateString))
        {
            // Only a private key
            Org.BouncyCastle.X509.X509Certificate bcCertificate = (X509Certificate)new PemReader(textReader).ReadObject();
            publicKey = bcCertificate.GetPublicKey();
        }

        return new AsymmetricCipherKeyPair(publicKey, privateKey);

    }

    public byte[] SignData(byte[] data, AsymmetricKeyParameter privateKey)
    {
        var signer = SignerUtilities.GetSigner("SHA-256withECDSA");

        signer.Init(true, privateKey);

        signer.BlockUpdate(data, 0, data.Length);

        return signer.GenerateSignature();
    }

    public bool VerifySignature(byte[] signature, AsymmetricKeyParameter publicKey)
    {

        var verifier = SignerUtilities.GetSigner("SHA-256withECDSA");

        verifier.Init(false, publicKey);

        verifier.BlockUpdate(signature, 0, signature.Length);

        return verifier.VerifySignature(signature);

    }

共有1个答案

方安怡
2023-03-14

波尔克先生是正确的,您需要使用验证器。用数据块更新,然后使用中的签名字节验证签名

签名本身无法验证。该算法需要数据作为输入,以在进入验证状态之前计算哈希值。当然,在没有数据的情况下验证签名只能提供有限的价值:您可以证明使用了私钥。

对于ECDSA,如果没有散列,也没有真正的选项来验证签名的任何部分

理论上,RSA / PKCS#1将允许您验证签名的内容至少是由私钥创建的,即使内容是未知的。因为可以检索完整的哈希值,所以可以猜测数据输入,而不必为每个可能的输入值进行签名验证。大多数API当然不适合这种签名的使用,因为这是特定于某些方案的。

 类似资料:
  • 我正在尝试使用C#和内置的加密库来验证使用EC密钥SHA256创建的签名。 我使用openssl创建了一个私钥和相应的证书: 以下是我正在使用的密钥(别担心,它们并不重要): 然后,我有一个包含字符串“Hello”的简单数据文件。然后,我使用openssl对该文件进行签名,如下所示: 然后,我可以通过首先从证书中提取公钥,然后使用公钥来验证签名: 然后,我尝试使用 C#(.NET Core 3.1

  • 我在开发安全系统时遇到了以下问题: 我们收到一些数据,我们必须通过签名进行验证。签名算法是ecdsa-with-SHA256,openssl_verify()似乎没有这个选项。已经尝试过搜索像phpseclib这样的独立PHP库了——也不走运,ecdsa-with-SHA1似乎是他们提供的最佳选择。 对于这个问题,什么是合适的解决方案?也许我错过了一些实现这种功能的库?

  • 下面是我的场景--我从条形码中读取数据,并将其转换为纯文本。本文是条码数据+数字签名的结合。数字签名附加在末尾,使我能够分离出实际数据和数字签名数据。数字签名数据使用sha256哈希-用户将公钥作为windows证书文件()发送给我。 所需实现:-需要从证书中提取公钥,并根据提供的条形码数据和数字签名验证公钥。 问题:

  • 我想创建一个签名并使用openssl验证它。我想有我的签名的十六进制输出。 这是我的密码 我得到这个错误: 如果我在创建签名的过程中删除了-hex,它就可以工作了。

  • 我需要使用256位的私钥为ECDSA的256位散列签名,就像比特币一样。由于缺少python中的ECDSA文档,我感到绝望。 我在网上找到了很多代码,但是没有什么比或类似的,我发现的所有东西都是我不懂的大量数学代码,但他们使用ecdsa库(我不知道为什么他们不在一个库中添加一个用于签名的签名函数,而是在使用库时需要一页代码?)。 这是目前为止我找到的最好的代码: 但我就是不能相信这样的代码,因为我

  • 我应该如何更改A方法?任何想法都是好的。提前谢谢。