Как подписать и проверить ECDSA с подписью SHA256 в C# - PullRequest
0 голосов
/ 30 марта 2020

У меня есть файл, содержащий закрытый ключ E C:

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

У меня есть сертификат с ключом publi c, который соответствует закрытому ключу:

In Формат 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-----

Я пытаюсь выполнить sh две вещи:

  1. Подписать массив байтов использование закрытого ключа с использованием алгоритма подписи ecdsa-with-SHA256
  2. Проверьте правильность подписи, используя ключ publi c в сертификате

Я пытался использовать Bouncy Castle библиотека. Вот что у меня так далеко. Мое утверждение не выполняется.

    [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 Ответ

0 голосов
/ 31 марта 2020

Mr Polk правильный , вам нужно использовать verifier.blockUpdate с данными, а затем использовать байты подписи в VerifySignature.

Подписи не могут быть проверены самостоятельно. Алгоритм требует данных в качестве входных данных для расчета значения ha sh перед входом в состояние проверки. Конечно, проверка подписи без данных дает только ограниченную ценность: вы можете просто доказать, что использовался закрытый ключ.

С ECDSA также нет реальной возможности проверить какую-либо часть подписи без ха sh


Теоретически RSA / PKCS # 1 позволит вам проверить, что содержимое подписи, по крайней мере, создано закрытым ключом, даже если содержимое неизвестно. Поскольку вы можете получить полное значение ha sh, можно угадать ввод данных без необходимости go на этапе проверки подписи для каждого возможного значения ввода. Большинство API, конечно, не ориентированы на такое использование подписей, поскольку это указано c для определенных схем.

...