Generat EC KeyPair with OpenSSL library

Viewed 304

I use the OpenSSL library to generate a keypair. Here is the code:

#include <openssl/obj_mac.h>
#include <openssl/ec.h>

// See: https://rjordaney.is/code_exercises/ecdsa_openssl/

OpenSslKey::OpenSslKey()
{
    EC_KEY *key_pair_obj = nullptr;;
    BIGNUM *priv_key;
    EC_POINT *pub_key;
    EC_GROUP *secp256k1_group;

    char *pub_key_char;
    char *priv_key_char;

    int ret_error;

    // Generate secp256k1 key pair
    key_pair_obj = EC_KEY_new_by_curve_name(NID_secp256k1);
    ret_error    = EC_KEY_generate_key(key_pair_obj);

    // Get private key
    priv_key      = (BIGNUM *)EC_KEY_get0_private_key(key_pair_obj);
    priv_key_char = BN_bn2hex(priv_key);

    // Get public key
    pub_key         = (EC_POINT *)EC_KEY_get0_public_key(key_pair_obj);
    secp256k1_group = EC_GROUP_new_by_curve_name(NID_secp256k1);
    pub_key_char    = EC_POINT_point2hex(secp256k1_group, pub_key, POINT_CONVERSION_UNCOMPRESSED, nullptr);
    EC_GROUP_free(secp256k1_group);

    printf("Private key: %s\n", priv_key_char);
    printf("Public key : %s\n", pub_key_char);
}

The output looks like this:

Pivate key: 83A2B7068D5DA6CA864F5E4232F51D59BAF229B65D59B4D2E0EB90ED04EF29CF
Public key: 04B6E78EACFDDD884EB28FAAF5549FBD7794CBFE236437A91965D9AC865178F5B9376400B4A0CEDC664A44934578246484F33395F452919C6F3EFC1D776029F9FF

How can I get the private and the public key in a DER format?

I added:

3056301006072a8648ce3d020106052b8104000a034200

in front of the public key and like this it looks like the public key is a valid key. Is that correct or does the OpenSSL library provide a function to convert the public key to DER?

What do I have to do to get associated private key in DER format? Is there also an uncompressed version of the private key?

Update: Here you can find my final version:

OpenSslKey::OpenSslKey()
{
    EC_KEY *key_pair_obj = nullptr;;
    BIGNUM *priv_key;
    EC_POINT *pub_key;
    EC_GROUP *secp256k1_group;

    char *pub_key_char;
    char *priv_key_char;

    int ret_error;

    // Generate secp256k1 key pair
    key_pair_obj = EC_KEY_new_by_curve_name(NID_secp256k1);
    ret_error    = EC_KEY_generate_key(key_pair_obj);

    // Get private key
    priv_key      = (BIGNUM *)EC_KEY_get0_private_key(key_pair_obj);
    priv_key_char = BN_bn2hex(priv_key);

    // Get public key
    pub_key         = (EC_POINT *)EC_KEY_get0_public_key(key_pair_obj);
    secp256k1_group = EC_GROUP_new_by_curve_name(NID_secp256k1);
    pub_key_char    = EC_POINT_point2hex(secp256k1_group, pub_key, POINT_CONVERSION_UNCOMPRESSED, nullptr);
    EC_GROUP_free(secp256k1_group);

    printf("Private key: %s\n", priv_key_char);
    printf("Public key : %s\n", pub_key_char);

    // Convert the private key to DER
    unsigned char *priv_key_char_der = nullptr;
    int priv_key_len_der = i2d_ECPrivateKey(key_pair_obj, &priv_key_char_der);

    // Convert the public key to der
    unsigned char *pub_key_char_der = nullptr;
    int pub_key_len_der = i2d_EC_PUBKEY(key_pair_obj, &pub_key_char_der);
}
1 Answers

What do I have to do to get associated private key in DER format?

OpenSSL provides several variations of the conversion functions i2d_ECPrivateKey() and i2d_EC_PUBKEY() that you can leverage for this. You can choose for the output to go to memory with i2d_ECPrivateKey, to a bio with i2d_ECPrivateKey_bio or to a file pointer with i2d_ECPrivateKey_fp.

For example, using the one that writes the private key in DER encoding to a file bio:

BIO *bio = BIO_new(BIO_s_file());
BIO_write_filename(bio, "private_key.der");
i2d_ECPrivateKey_bio(bio, key_pair_obj);
BIO_free(bio);

For both the private and public key conversion functions, note that the input is the key_pair_obj, of the type EC_KEY.

Is there also an uncompressed version of the private key?

There is no uncompressed version of the private part of the key pair. For some explanation, see ECC Keys

Related