2

This question is likely to be a duplicate, I apologize if so, but cannot google a solution.

Given:

RSA* rsa = RSA_generate_key(2048, RSA_3, NULL, NULL);

I would like to have something like:

const char* pubKey = pubKeyFromRSA(rsa);
const char* privKey = privKeyFromRSA(rsa);

//and then convert it back
RSA* newRSA = RSAFromPrivKey(privKey);

How do I do that? Thanks

Andrey Chernukha
  • 21,488
  • 17
  • 97
  • 161
  • Of course I have – Andrey Chernukha Mar 29 '19 at 17:31
  • 2
    Does this link give you what you need? https://stackoverflow.com/questions/5927164/how-to-generate-rsa-private-key-using-openssl – Michael Dorgan Mar 29 '19 at 17:35
  • You could access the rsa struct directly. Is this helpful? https://stackoverflow.com/questions/10512295/openssl-what-does-rsa-n-e-d-p-q-parameters-represent – MFisherKDX Mar 29 '19 at 17:42
  • @MichaelDorgan this looks promising. Thanks – Andrey Chernukha Mar 29 '19 at 17:50
  • RSA struct contains lots of stuff. Why do you think you can get it back from just those two things? https://www.openssl.org/docs/man1.0.2/man3/rsa.html – stark Mar 29 '19 at 17:53
  • @stark because I can get it back (and it decrypts) from d, n, p and q numbers. I assume a string representation should also be enough – Andrey Chernukha Mar 29 '19 at 17:55
  • 1
    @MFisherKDX: not in 1.1.0 up, which in 9 months will be the only supported upstream versions. Andrey: do you want to recover only within the same process, or in a different process, system, or program? The latter require you convert to a serialized form and back; the two serialized forms (directly) supported by OpenSSL are der and pem, as detailed by jww in #5927164, although you can implement something else if you want – dave_thompson_085 Mar 29 '19 at 18:50
  • @dave_thompson_085 within the same process – Andrey Chernukha Mar 29 '19 at 19:25
  • 2
    Consider [`i2d_RSAPrivateKey`](https://www.openssl.org/docs/man1.1.0/man3/d2i_RSAPrivateKey.html) and `d2i_RSAPrivateKey`. They are probably not the most compact and efficient serializations possible but they are directly supported by stable APIs. – President James K. Polk Mar 29 '19 at 20:15
  • @MichaelDorgan your solution helped me. thanks again. If you make an answer I will accept. Or I can answer the question myself – Andrey Chernukha Mar 30 '19 at 08:27
  • Possible duplicate of [How to generate RSA private key using OpenSSL?](https://stackoverflow.com/questions/5927164/how-to-generate-rsa-private-key-using-openssl) – Konrad Rudolph Apr 01 '19 at 17:26

1 Answers1

0

Thanks to Michael Dorgan who pointed me in the right direction. I ended up having these two functions:

const char* keyFromRSA(RSA* rsa, bool isPrivate)
{
    BIO *bio = BIO_new(BIO_s_mem());

    if (isPrivate)
    {
        PEM_write_bio_RSAPrivateKey(bio, rsa, NULL, NULL, 0, NULL, NULL);
    }
    else
    {
        PEM_write_bio_RSA_PUBKEY(bio, rsa);
    }

    const int keylen = BIO_pending(bio);
    char* key = (char *)calloc(keylen+1, 1);
    BIO_read(bio, key, keylen);
    BIO_free_all(bio);

    return key;
}

RSA* rsaFromPrivateKey(const char* aKey)
{
     RSA* rsa = NULL;
     BIO *bio = BIO_new_mem_buf(aKey, strlen(aKey));
     PEM_read_bio_RSAPrivateKey(bio, &rsa, 0, 0);
     BIO_free_all(bio);

     return rsa;
}
Andrey Chernukha
  • 21,488
  • 17
  • 97
  • 161