Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
I have a self-signed certificate(not popular X.509 one). The certificate and ECDSA public/private key pair are generated by java program using bouncy castle.
I need to verify this certificate with C program using openssl. However, the ECDSA signature can be verified by java program correctly, but failed with openssl verification. If I use the same private key to re-sign the message with openssl, the signature verification with openssl would passed though.
Here is the java code snippet related to key generation.(After key pair generated, I actually save them in file, so it will always use the the same key, not shown in following snipet).
KeyPair rootCASigningKeys = cryptoManager.generateKeyPair(SignatureChoices.ecdsaNistP256Signature);
BCECPublicKey bcPub = cryptoManager.toBCECPublicKey(PublicKeyAlgorithm.ecies_nistp256, (java.security.interfaces.ECPublicKey) rootCASigningKeys.getPublic());
ECPublicKey pk = (java.security.interfaces.ECPublicKey) rootCASigningKeys.getPublic();
ECPrivateKey priv = (ECPrivateKey) rootCASigningKeys.getPrivate();
System.out.println("pubkeyX="+getHexString(pk.getW().getAffineX().toByteArray()));
System.out.println("pubkeyY="+getHexString(pk.getW().getAffineY().toByteArray()));
System.out.println("privatekey="+getHexString(priv.getS().toByteArray()));
The C code of verify the signature showed in bellow:
bool v2x_ecdsa_verify(
const uint8_t *digest,
size_t dgstlen,
const void *sig,
const void *pkey)
ECDSA_SIG *ecdsa_sig;
EC_KEY *ec_key;
EC_GROUP *grp
int ret;
/* debug */
EC_POINT *ecpt;
/* debug end */
grp = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1); /*TODO: */
ecpt = EC_KEY_get0_public_key((const EC_KEY *)pkey);
struct ec_point_st *cpt = (struct ec_point_st *)ecpt;
printf("Pubkey_x:%d=\n", BN_num_bytes(&cpt->X));
BN_print_fp(stdout, &cpt->X);
printf("Pubkey_y:%d=\n", BN_num_bytes(&cpt->Y));
BN_print_fp(stdout, &cpt->Y);
printf("\n");
printf("digest dump\n");
v2x_dump_hex(V2X_LOG_ERR, digest, 32);
printf("\n");
/* DEBUG code, Use the private key outputed by Java code to re-sign the digest */
uint8_t priv_buf[] = {
0x00, 0xB2, 0x6C, 0x1D, 0x0C, 0x62, 0x84, 0x45, 0x31, 0x3C, 0xF3, 0x83, 0x1D, 0x4E, 0xA7, 0x4B,
0x2C, 0x07, 0x19, 0xCF, 0x19, 0xCC, 0x3E, 0xA7, 0xE5, 0x4F, 0xA4, 0xF0, 0x91, 0xBF, 0x5B, 0x96, 0xE8};
BIGNUM *priv_bn = BN_bin2bn(priv_buf, sizeof(priv_buf), NULL);
printf("priv_bn=\n");
BN_print_fp(stdout, priv_bn);
printf("\n");
if (!priv_bn) {
V2X_ERR("Failed to conver privkey \n");
return false;
EC_KEY *priv_key = EC_KEY_new();
if (priv_key) {
if (!EC_KEY_set_group(priv_key, grp)) {
V2X_ERR("Failed to set group\n");
return false;
EC_KEY_set_private_key(priv_key, priv_bn);
ecdsa_sig = v2x_ecdsa_sign(digest, dgstlen, NULL, 0, (void *)priv_key);
/* END of DEBUG code */
//ret = ECDSA_do_verify(digest, dgstlen, (ECDSA_SIG *)sig, (EC_KEY *)pkey); /* It fail to verify original signature */
ret = ECDSA_do_verify(digest, dgstlen, ecdsa_sig, (EC_KEY *)pkey); /* it pass to verify the re-signed signature */
if (ret < 0)
V2X_ERR("ret=%d\n", ret);
return (bool)ret;
The keys printed out by java and C are in bellow :
Java using bouncy castle:
provider=BC
pubkeyX=00 E4 B6 E1 50 C2 7A 85 DD BD 92 F8 14 C9 0E B0 5E 1E 28 A6 3C A3 B6 B1 69 32 39 BF 1B 1B F0 B0 03
pubkeyY=00 ED DC 75 F0 E9 36 05 25 5F 54 08 74 E7 9D 6E BC 1B DF 97 5A E4 D2 A7 04 A7 E0 5F 21 06 54 26 1E
privatekey=00 B2 6C 1D 0C 62 84 45 31 3C F3 83 1D 4E A7 4B 2C 07 19 CF 19 CC 3E A7 E5 4F A4 F0 91 BF 5B 96 E8
And the sha256 hash being signed is
F40D983058408C0519D7E238BEBFA5EDCAA7F3B86AD4C83847F5DD66EA1C051B
C Using OpenSSL
Pubkey_x:32=
E4B6E150C27A85DDBD92F814C90EB05E1E28A63CA3B6B1693239BF1B1BF0B003
Pubkey_y:32=
EDDC75F0E93605255F540874E79D6EBC1BDF975AE4D2A704A7E05F210654261E
digest dump
f4 0d 98 30 58 40 8c 05 19 d7 e2 38 be bf a5 ed
ca a7 f3 b8 6a d4 c8 38 47 f5 dd 66 ea 1c 05 1b
priv_bn=
B26C1D0C628445313CF3831D4EA74B2C0719CF19CC3EA7E54FA4F091BF5B96E8
I am pretty stuck here, java program can sign and verify that given digest, and C program can sign and verify the same digest using same key pair. But the C program can NOT verify the signature generated by java program. I also dumped out the generated signature r/s portion from java and compared with what i am trying to verify in C program , they are the same.
I can go deeper into OpenSSL to add debug, but too bad I am not expert in java bouncy castle. Any suggestion is greatly appreciated! Thanks and sorry for the long post.
–
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.