Reputation: 195
I have a file containing an EC private key:
-----BEGIN EC PRIVATE KEY-----
<data>
-----END EC PRIVATE KEY-----
I have a certificate with a public key that corresponds to the private key:
In pem format:
-----BEGIN CERTIFICATE-----
<data>
-----END CERTIFICATE-----
In txt format:
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-----
I am trying to accomplish two things:
I have tried using the Bouncy Castle library. Here is what I have so far. My assertion is failing.
[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);
}
Upvotes: 2
Views: 21394
Reputation: 93948
Mr Polk is correct, you need to use verifier.blockUpdate
with the data, and then use the signature bytes in VerifySignature
.
Signatures cannot be verified on their own. The algorithm requires the data as input to calculate the hash value before entering the validation state. Of course having the signature verified without the data only provides limited value: you can just prove that the private key was used.
With ECDSA there is also no real option to verify any part of the signature without the hash
RSA / PKCS#1 in theory would allow you to verify that the contents of the signature are at least created by the private key, even though the contents are unknown. As you can retrieve the full hash value, it is possible to guess the data input without having to go through the signature verification phase for each possible input value. Most API's are of course not geared towards such use of signatures as this is specific to certain schemes.
Upvotes: 4