0

I have the following code for printing and generating a public and private key:

#include <openssl/err.h>
#include <openssl/ec.h>
#include <openssl/pem.h>


int main() 
{

    BIO* outbio = NULL;
    EC_KEY* myecc = NULL;
    EVP_PKEY* pkey = NULL;

    outbio = BIO_new_fp(stdout, BIO_NOCLOSE);

    myecc = EC_KEY_new_by_curve_name(NID_secp256k1);
    EC_KEY_generate_key(myecc);
    pkey = EVP_PKEY_new();
    EVP_PKEY_assign_EC_KEY(pkey, myecc);

    myecc = EVP_PKEY_get1_EC_KEY(pkey);
    const EC_GROUP* ecgrp = EC_KEY_get0_group(myecc);
    BIO_printf(outbio, "ECC Key size: %d bit\n", EVP_PKEY_bits(pkey));
    BIO_printf(outbio, "ECC Key type: %s\n", OBJ_nid2sn(EC_GROUP_get_curve_name(ecgrp)));

    PEM_write_bio_PrivateKey(outbio, pkey, NULL, NULL, 0, 0, NULL);
    PEM_write_bio_PUBKEY(outbio, pkey);
} 

This produces output such as this:

ECC Key size: 256 bit
ECC Key type: secp256k1
-----BEGIN PRIVATE KEY-----
MIGEAgEAMBAGByqGSM49AgEGBSuBBAAKBG0wawIBAQQgFAwnckdtDYrNJUbl+sxv
wkUEZCaZTy69C/Mo957vlRihRANCAARgj+NiB2pCJkwb3yPmbD6Rxf/DIgOnbUwr
6sQrmwgq7kBqKVYp7Ar6GdqmnvXB/fSWBWCBzgT6oJO6v5Ixc0T2
-----END PRIVATE KEY-----
-----BEGIN PUBLIC KEY-----
MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEYI/jYgdqQiZMG98j5mw+kcX/wyIDp21M
K+rEK5sIKu5AailWKewK+hnapp71wf30lgVggc4E+qCTur+SMXNE9g==
-----END PUBLIC KEY-----

This looks correct, however if I try to apply these keys to https://8gwifi.org/ecsignverify.jsp the keys do not function properly. If I put the keys in the public/private key input boxes, I get "null EC Private Key is not valid for Signature generation". I do not understand at all what the problem is.

Secondly, I intend to store these keys in some type of string format so that I can load them into memory easily. But how would I go about doing both a signing and verification using these two keys in string format in OpenSSL? I do not understand the ECDSA_sign function parameters nor the ECDSA_verify function parameters.

  • Don't trust any website that doesn't clearly specify how data is encoded decoded. They use a `EC PRIVATE KEY` instead of a `PRIVATE KEY`, which means that the bytes within the base 64 encoding are treated differently. Try and use `openssl asn1parse` or a website like [this site](https://lapo.it/asn1js/#MHQCAQEEIKRPdj7XMkxO8nehl7iYF9WAnr2Jdvo4OFqceqoBjc8_oAcGBSuBBAAKoUQDQgAE7qXaOiK9jgWezLxemv-lxQ_9_Q68pYCox_y1vD1fhvosggCxIkiNOZrDkHqms0N-huh92A_vfI5FyDZx0-cHww) to have a look inside. – Maarten Bodewes Aug 20 '22 at 16:00
  • The website requires a private EC key in SEC1 format, while your private key is in PKCS#8 format. You can convert your key e.g. with OpenSSL or online here: https://8gwifi.org/pemconvert.jsp – Topaco Aug 20 '22 at 16:01
  • Perfect. It works now. Although for some weird reason I only can and need to convert the private key from my code, the public key stays unconverted. I don't understand why the private key needs to be converted where as the public key doesn't –  Aug 20 '22 at 16:13
  • For keys, different formats are possible. Regarding the private key, the formats of code and website differ (which is why a conversion is necessary), regarding the public key they do not (which is why no conversion is necessary). There is nothing more behind it. – Topaco Aug 20 '22 at 16:31
  • I understand. It's still seems needlessly confusing. I don't understand why the two similar functions I'm using would have two different formats, it's inconvenient EDIT: Pretty sure it's the website requiring two different formats but still –  Aug 20 '22 at 16:39
  • Try to familiarize yourself with the different formats for EC keys on the web (private: SEC1 and PKCS#8, public: X.509 aka SPKI), then it will probably be easier to understand. – Topaco Aug 20 '22 at 17:10
  • Alright, that makes sense –  Aug 20 '22 at 17:33

0 Answers0