I'm trying to make use of elliptic curve crypto. I need two implementations of the same thing, one in Java and one in C. I'm testing them using two key pairs which were generated using the curve secp256k1. When I generate the derived secret in Java I always get a different number from what I get from OpenSSL.
Java code:
/* privateKey and peerPublicKey are generated with the following parameters */
ECParameterSpec paramSpec = ECNamedCurveTable.getParameterSpec("secp256k1");
/* ... */
Provider BC = new BouncyCastleProvider();
KeyAgreement agr = KeyAgreement.getInstance("ECDH", BC);
agr.init(privateKey);
agr.doPhase(peerPublicKey, true);
byte[] secret = agr.generateSecret();
C code
/* pkey and peerkey are generated using EC_KEY_new_by_curve_name(NID_secp256k1) */
/* and than wrapped in an EVP_PKEY */
EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pkey, NULL);
uint8_t *secret = NULL;
size_t secret_len;
EVP_PKEY_derive_init(ctx);
EVP_PKEY_derive_set_peer(ctx, peerkey);
EVP_PKEY_derive(ctx, NULL, &secret_len);
secret = malloc(secret_len);
EVP_PKEY_derive(ctx, secret, &secret_len);
I'm sure that the keys are valid and that they are the same both in C and in Java code, but I don't understand why the derived secret is different. Am I missing something?
Thanks
This code looks like its missing a few steps. For example,
EVP_PKEY_paramgen_init
is not present.The OpenSSL wiki has an example at Elliptic Curve Diffie-Hellman. I'm going to copy/paste it below to avoid the link-only answer, but I believe its the work of Matt Caswell.
Each run of the protocol will produce different results. That's because each party picks a random value for each run of the protocol. That is, the
a
ing^a
is random and different for each run, so the public keyA = g^a
is different for each run.If everything is working correctly, you'll never see the parties use the same values, or one party to reuse a past value. Independent executions will never produce the same result. It does not matter if its OpenSSL ↔ OpenSSL, OpenSSL ↔ Java, or Java ↔ Java. They will always produce different results.