micro-ecc: Failure to verify against openssl
I built the library and am running under osx. I am using the secp256r1 curve.
If I run the example to sign / verify using uECC it will verify.
What fails is when I try to use uECC to verify a signature generated by openssl, or use openssl to verify using a signature generated by uECC.
I have generated a private key with openssl and verified that uECC_make_public_key() will generate the same public key that openssl is getting so I am confident the curve is matching.
My key generation, signing and verification script:
openssl ec -in private.pem -pubout -out public.pem #-conv_form uncompressed
openssl ec -in private.pem -text
touch msg.txt | echo -n "aaa" > msg.txt
openssl dgst -sha256 -out msg.digest.txt msg.txt
cat msg.digest.txt
openssl dgst -sha256 -sign private.pem -out msg.signature.txt msg.digest.txt
openssl asn1parse -inform DER -in msg.signature.txt
python3 dumpsig.py <msg.signature.txt
openssl dgst -sha256 -hex -verify public.pem -signature msg.signature.txt msg.digest.txt
And output of script:
writing EC key
read EC key
Private-Key: (256 bit)
priv:
5f:ef:5f:e5:62:7c:ff:60:56:87:3e:64:87:32:72:
c3:ed:8c:08:c4:b6:01:b1:3c:36:c0:db:c2:bb:8d:
24:fc
pub:
04:f1:bf:ca:c9:3c:ff:50:71:4f:7d:cc:1c:23:e7:
03:02:d1:81:8e:88:52:20:43:01:8a:3e:68:98:78:
9b:8a:9f:48:a2:a8:43:f4:2a:e3:3c:5a:da:d8:90:
bc:5d:f3:87:98:64:fb:b8:ea:e7:ea:95:5e:39:84:
3a:85:44:a3:49
ASN1 OID: prime256v1
NIST CURVE: P-256
writing EC key
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIF/vX+VifP9gVoc+ZIcycsPtjAjEtgGxPDbA28K7jST8oAoGCCqGSM49
AwEHoUQDQgAE8b/KyTz/UHFPfcwcI+cDAtGBjohSIEMBij5omHibip9IoqhD9Crj
PFra2JC8XfOHmGT7uOrn6pVeOYQ6hUSjSQ==
-----END EC PRIVATE KEY-----
SHA256(msg.txt)= 9834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0
0:d=0 hl=2 l= 68 cons: SEQUENCE
2:d=1 hl=2 l= 32 prim: INTEGER :58CF628E0597B8AE32BD8199C6E7DF0192A50CF3AAC07F66769286FB00F45815
36:d=1 hl=2 l= 32 prim: INTEGER :78235F960F70E5641B6F1CCE080F897F20722541BDD6A81FFA5DF3C2B130FAEB
signature(70) = 3044022058cf628e0597b8ae32bd8199c6e7df0192a50cf3aac07f66769286fb00f45815022078235f960f70e5641b6f1cce080f897f20722541bdd6a81ffa5df3c2b130faeb
Verified OK
My uECC test code is simply:
char sig[] = "58CF628E0597B8AE32BD8199C6E7DF0192A50CF3AAC07F66769286FB00F4581578235F960F70E5641B6F1CCE080F897F20722541BDD6A81FFA5DF3C2B130FAEB";
char priv[] = "5fef5fe5627cff6056873e64873272c3ed8c08c4b601b13c36c0dbc2bb8d24fc";
void uECC_test(void)
{
int r;
const struct uECC_Curve_t * curve = uECC_secp256r1();
uint8_t private1[32];
uint8_t public1[64];
uint8_t signature[64];
uint8_t hash[32] = {0x98, 0x34, 0x87, 0x6D, 0xCF, 0xB0, 0x5C, 0xB1, 0x67, 0xA5, 0xC2, 0x49, 0x53, 0xEB, 0xA5, 0x8C, 0x4A, 0xC8, 0x9B, 0x1A, 0xDF, 0x57, 0xF2, 0x8F, 0x2F, 0x9D, 0x09, 0xAF, 0x10, 0x7E, 0xE8, 0xF0};
dump("hash", hash, sizeof(hash));
strtobytes(priv, private1);
dump("priv", private1, sizeof(private1));
uECC_compute_public_key(private1, public1, curve);
dump("pub ", public1, sizeof(public1));
memset(signature, 0xDB, sizeof(signature));
r = uECC_sign(private1, hash, sizeof(hash), signature, curve);
// strtobytes(sig, signature); // if to override uECC signature with openssl signature
dump("sig ", signature, sizeof(signature));
r = uECC_verify(public1, hash, sizeof(hash), signature, curve);
printf("verify result = %d\n", r);
}
When I run that using the signature generated by uECC, it works and I get:
priv (32): 5fef5fe5627cff6056873e64873272c3ed8c08c4b601b13c36c0dbc2bb8d24fc
pub (64): f1bfcac93cff50714f7dcc1c23e70302d1818e88522043018a3e6898789b8a9f48a2a843f42ae33c5adad890bc5df3879864fbb8eae7ea955e39843a8544a349
sig (64): 9fff2fceeb0015300030b78b5c930340408c2145390980e3b4bdff613eb4658e9690d1c9c970bdc1f16fee457d550ede4758df8ea3e24dfb3dee2d6481f1cf98
verify result = 1
If I override the signature generated by uECC (uncomment the strtobytes call), I get:
priv (32): 5fef5fe5627cff6056873e64873272c3ed8c08c4b601b13c36c0dbc2bb8d24fc
pub (64): f1bfcac93cff50714f7dcc1c23e70302d1818e88522043018a3e6898789b8a9f48a2a843f42ae33c5adad890bc5df3879864fbb8eae7ea955e39843a8544a349
sig (64): 58cf628e0597b8ae32bd8199c6e7df0192a50cf3aac07f66769286fb00f4581578235f960f70e5641b6f1cce080f897f20722541bdd6a81ffa5df3c2b130faeb
verify result = 0
I have the same issue if I take the 64-byte signature generated by uECC above, converting it to asn1/DER format and trying to get openssl to verify the signature.
$ python3 mksig.py 9fff2fceeb0015300030b78b5c930340408c2145390980e3b4bdff613eb4658e9690d1c9c970bdc1f16fee457d550ede4758df8ea3e24dfb3dee2d6481f1cf98 >junk
$ openssl asn1parse -inform DER -in junk
0:d=0 hl=2 l= 70 cons: SEQUENCE
2:d=1 hl=2 l= 33 prim: INTEGER :9FFF2FCEEB0015300030B78B5C930340408C2145390980E3B4BDFF613EB4658E
37:d=1 hl=2 l= 33 prim: INTEGER :9690D1C9C970BDC1F16FEE457D550EDE4758DF8EA3E24DFB3DEE2D6481F1CF98
$ openssl dgst -sha256 -hex -verify public.pem -signature junk msg.digest.txt
Verification Failure
Is there a reason that this is not working for me? I understand that this is for embedded systems and that is where I plan to use it, but I wanted to at least sanity check it on a more friendly platform before investing more time with it.
Thank you.
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Comments: 18 (1 by maintainers)
The issue is that when you run ‘openssl dgst -sha256 -sign private.pem -out msg.signature.txt msg.digest.txt’, it hashes whatever the input is (msg.digest.txt) in this case, and signs the result of that. If you instead run ‘openssl dgst -sha256 -sign private.pem -out msg.signature.txt msg.txt’, everything works as expected.
and then the C code using uECC to verify: