Search code examples
copensslopensshlibcrypto

Build OpenSSL RSA from components


I've looked just about everywhere for the answer to this, but I think what I really need is for someone with relevant experience with OpenSSL to point me in the right direction.

In Python there's a library, PyCryptodome, which has pure Python implementations of several cryptography algorithms, including RSA. They have a function as a part of the RSA module called construct which builds an RSA key out of its various components (n, e, d, p, and q). I haven't been able to find a similar function in OpenSSL though, likely just because I don't know where to look in their documentation.

Any help would be greatly appreciated.


Solution

  • OpenSSL allows you to provide these values by creating your own RSA struct (via RSA_new()) and then populating it via RSA_set0_key, RSA_set0_factors, and RSA_set0_crt_params.

    Note that you can completely define an RSA public/private key with just n, e, d, but there are several additional values traditionally provided (e.g. p and q are the primes that form the modulus while iqmp, dmp1 and dmq1 are CRT coefficients).

    OpenSSL requires you to provide these as BN * instances and you must not free the BN instances after assigning them via the set0 functions. When you see a function with that naming scheme in OpenSSL it means you're setting a value, but it does not increment the reference count so if you free the BN * yourself it will become an invalid pointer in the struct.

    You can see exactly how this works in the pyca/cryptography source, but I strongly recommend against doing this yourself unless you're very comfortable with OpenSSL and its foibles.