<p>Usually you'd just pass around the EVP_PKEY structure to other OpenSSL calls.</p>
<p>To put the secret into memory, you can use</p>
<pre><code>char* secret_key;
BIO* bio_priv = BIO_new(BIO_s_mem());
PEM_write_bio_PrivateKey(bio_priv, pkey, NULL, NULL, 0, NULL, NULL);
BIO_get_mem_data(bio_priv, &amp;secret_key);
...
BIO_free(bio_priv);
</code></pre>
<p>This will set <code>secret_key</code> to point at the data inside <code>bio_priv</code> (before it is freed) containing the secret key. You can similarly use <code>PEM_write_bio_PUBKEY</code> to get the public key.</p>
<p>Also note there is a cryptography library designed specifically for the secp256k1 curve and Bitcoin, which is used by Bitcoin Core, so you could use that instead of OpenSSL. It can be found <a href="https://github.com/bitcoin-core/secp256k1" rel="nofollow noreferrer">here</a>.</p>

CC BY-SA 4.0
2021-12-26T11:06:21.617Z
Note `PEM_write*_PrivateKey` (since 1.0.0 in 2010) writes PKCS8-format (PEM label 'PRIVATE KEY'). OP's 'something like' is vague, but if they specifically want the SECG format 'EC PRIVATE KEY' use `PEM_write*_ECPrivateKey` instead. On the publickey side, setting compression (or not) may be important, and openssl commandline never uses the 'bare' X9/SECG format(s) but Bitcoin does -- a lot.
dave_thompson_085
CC BY-SA 4.0
2021-12-25T23:52:08.190Z
2021-12-26T00:21:04.467Z
2021-12-26T00:21:04.467Z
meshcollider
<p>I have 2 questions:</p>
<ol>
<li>How can I generate private/public key pairs with c++ and openssl? I don't want them saved to a file. I want the values to be available to my c++ program.</li>
<li>Given a private key, how can I regenerate its public key with c++ and openssl?</li>
</ol>
<p>For the first question, I need to do something like this, except in c++.</p>
<pre><code>$ openssl ecparam -name secp256k1 -genkey | openssl ec -text
read EC key
Private-Key: (256 bit)
priv:
    0c:25:3a:f2:dc:5b:07:b0:45:9c:ad:ac:13:e1:ef:
    14:50:68:cc:cc:6b:8b:09:66:1b:8d:c1:a4:f8:e8:
    ab:df
pub:
    04:8c:a7:6e:b0:23:8f:ad:c9:b0:4b:35:b7:65:1d:
    4d:67:1b:6a:5d:be:9e:84:14:99:97:4f:bf:d2:46:
    16:0f:14:e3:71:08:13:2c:c1:3b:95:1a:38:92:1c:
    cf:79:5d:9b:2e:18:64:47:8e:1f:4c:b2:5e:42:f4:
    47:1d:e4:81:d5
ASN1 OID: secp256k1
writing EC key
-----BEGIN EC PRIVATE KEY-----
MHQCAQEEIAwlOvLcWwewRZytrBPh7xRQaMzMa4sJZhuNwaT46KvfoAcGBSuBBAAK
oUQDQgAEjKdusCOPrcmwSzW3ZR1NZxtqXb6ehBSZl0+/0kYWDxTjcQgTLME7lRo4
khzPeV2bLhhkR44fTLJeQvRHHeSB1Q==
-----END EC PRIVATE KEY-----
</code></pre>
<p>The only thing I've been able to find are limited examples which got me nowhere. Here is what I have (with error checking removed for readability).</p>
<pre><code>EVP_PKEY_CTX* pkey_context = EVP_PKEY_CTX_new_id (EVP_PKEY_EC, NULL);
EVP_PKEY_keygen_init (pkey_context);
EVP_PKEY_CTX_set_ec_paramgen_curve_nid (pkey_context, NID_secp256k1);
EVP_PKEY *pkey = NULL;
EVP_PKEY_keygen (pkey_context, &amp;pkey);
cout &lt;&lt; &quot;pkey = &quot; &lt;&lt; pkey &lt;&lt; &quot;\n&quot;;
EVP_PKEY_CTX_free (pkey_context);
</code></pre>
<p>The result of this code is:</p>
<pre><code>pkey = 0x55f94ba2ca10
</code></pre>
<p>It prints the pointer to the variable, but I can't even find a definition of EVP_PKEY, so I have no way of knowing what is in that object.</p>
<p>Any help in figuring this out, or pointing me to better documentation, would be greatly appreciated.</p>

<private-key><public-key><c++><openssl>
How to generate private/public key pairs in c++ using openssl
Zephyrus
# How to generate private/public key pairs in c++ using openssl

(Asked by: username_0 on 2021-12-25)

I have 2 questions:

1. How can I generate private/public key pairs with c++ and openssl? I don't want them saved to a file. I want the values to be available to my c++ program.
2. Given a private key, how can I regenerate its public key with c++ and openssl?

For the first question, I need to do something like this, except in c++.

```
$ openssl ecparam -name secp256k1 -genkey | openssl ec -text
read EC key
Private-Key: (256 bit)
priv:
    0c:25:3a:f2:dc:5b:07:b0:45:9c:ad:ac:13:e1:ef:
    14:50:68:cc:cc:6b:8b:09:66:1b:8d:c1:a4:f8:e8:
    ab:df
pub:
    04:8c:a7:6e:b0:23:8f:ad:c9:b0:4b:35:b7:65:1d:
    4d:67:1b:6a:5d:be:9e:84:14:99:97:4f:bf:d2:46:
    16:0f:14:e3:71:08:13:2c:c1:3b:95:1a:38:92:1c:
    cf:79:5d:9b:2e:18:64:47:8e:1f:4c:b2:5e:42:f4:
    47:1d:e4:81:d5
ASN1 OID: secp256k1
writing EC key
-----BEGIN EC PRIVATE KEY-----
MHQCAQEEIAwlOvLcWwewRZytrBPh7xRQaMzMa4sJZhuNwaT46KvfoAcGBSuBBAAK
oUQDQgAEjKdusCOPrcmwSzW3ZR1NZxtqXb6ehBSZl0+/0kYWDxTjcQgTLME7lRo4
khzPeV2bLhhkR44fTLJeQvRHHeSB1Q==
-----END EC PRIVATE KEY-----

```

The only thing I've been able to find are limited examples which got me nowhere. Here is what I have (with error checking removed for readability).

```
EVP_PKEY_CTX* pkey_context = EVP_PKEY_CTX_new_id (EVP_PKEY_EC, NULL);
EVP_PKEY_keygen_init (pkey_context);
EVP_PKEY_CTX_set_ec_paramgen_curve_nid (pkey_context, NID_secp256k1);
EVP_PKEY *pkey = NULL;
EVP_PKEY_keygen (pkey_context, &pkey);
cout << "pkey = " << pkey << "\n";
EVP_PKEY_CTX_free (pkey_context);

```

The result of this code is:

```
pkey = 0x55f94ba2ca10

```

It prints the pointer to the variable, but I can't even find a definition of EVP\_PKEY, so I have no way of knowing what is in that object.

Any help in figuring this out, or pointing me to better documentation, would be greatly appreciated.

**Tags:** private-key, public-key, c++, openssl


---

## 1 answers

### Answer by username_1 on 2021-12-25. Score: 2

Usually you'd just pass around the EVP\_PKEY structure to other OpenSSL calls.

To put the secret into memory, you can use

```
char* secret_key;
BIO* bio_priv = BIO_new(BIO_s_mem());
PEM_write_bio_PrivateKey(bio_priv, pkey, NULL, NULL, 0, NULL, NULL);
BIO_get_mem_data(bio_priv, &secret_key);
...
BIO_free(bio_priv);

```

This will set `secret_key` to point at the data inside `bio_priv` (before it is freed) containing the secret key. You can similarly use `PEM_write_bio_PUBKEY` to get the public key.

Also note there is a cryptography library designed specifically for the secp256k1 curve and Bitcoin, which is used by Bitcoin Core, so you could use that instead of OpenSSL. It can be found [here](https://github.com/bitcoin-core/secp256k1).

> **Comments:**
> **username_2**: Note `PEM_write*_PrivateKey` (since 1.0.0 in 2010) writes PKCS8-format (PEM label 'PRIVATE KEY'). OP's 'something like' is vague, but if they specifically want the SECG format 'EC PRIVATE KEY' use `PEM_write*_ECPrivateKey` instead. On the publickey side, setting compression (or not) may be important, and openssl commandline never uses the 'bare' X9/SECG format(s) but Bitcoin does -- a lot.  

---

