Reputation: 5146
I have information about n,p,q where n=pq and p and q are large prime numbers to be used for the RSA algorithm. For example:
n: C053094BFABF26D431CF33E028770DBB15F4AE76820B5150181F1BF42C5CF3AA7BDB459ACA77D610497F94FFA017BC07EF030E3D3450CAE7E706F352B7D7575CA6B89A5B3C953028E562F7F698C97FDD490EDF4788F073362C743B70AF2C61A17FA495E5801CC8EA1A732C9E8985DB4E8A22EAB97407806F8D7CDDF0BF3CD9F3
e: 10001
p: D9CC00CD811FB052A0EF27332597DA89AAA6B042A1A01A8944229EE680C964148BB07AFBD2EBE467CC9B28E41B5897132F9AFDCD7C5B794CD37E3245A0BC18F5
q: E20F35A3B49B49A35DE25E285EE9B2DC5F3B5FDDD281892F4BE3C54768CBE09272667FF137C5ED9CADD42FF18A8B08FFA9A82C0CF26169B0940F60BEF2AD7647
I want to generate a PEM private and public key from that values.
I guess they are on hexadecimal format, but I really don't know which is contained in a key in pem format. I know that PEM just means that the key is base64 with some other additions footers (begin public etc.).
Any suggestions or any example code?
I mean my goal is from that value obtain two file in PEM private and public keys to be passed to openssl for example.
Many thanks, Andrea
Upvotes: 0
Views: 5775
Reputation: 411
This is a sample for RSA in a VB.NET project.
STEP 1
First, you must format your N,E,P,Q,DP,DQ,InverseQ,D key data (all of them!! See later) in base64 and build with them a XML structured string (or file) like this:
<RSAKeyValue>
<Modulus>vbBYUkGHX4YI1Rcovx+Ewz2OW1Iix</Modulus>
<Exponent>AQ...</Exponent>
<P>5w/iuGIBZdTYasdfalksdkkdkdksdldfdfs</P>
<Q>0ilXTMYjwhp+JvQPo3gnRAF0EgoHPm6tBt1</Q>
<DP>JS2gLEzQrsLlnlkQCRZ55+RtM6cphJSa5x</DP>
<DQ>RMWugbsdHHma6phXPcEl6EUpfHW3pSCGko</DQ>
<InverseQ>h54IMS+ZabAn/WzOFTApgB4y16Az</InverseQ>
<D>OjnoUo+E02CcU3TBcDFnmlrJ2ORUcXCy5FB</D>
</RSAKeyValue>
(Of course these one is fake, dont try to use it or will throw error)
As dajames said, you must also have D,DP,DQ and InverseQ. If you don't have them, things get more complicated but not impossible, because you must calculate them by yourself. The easiest way (for me) was accessing the source code of the tool that build P and Q numbers for me. Inside it, there were classes to operate with this kind of big numbers. By slightly modifying the code, I could calculate:
DP = ( 1 / Exponent) mod ( P - 1 )
DQ = (1 / Exponent ) mod ( Q - 1 )
InverseQ = ( 1 / Q ) mod P where P > Q
See last line, you must take into account that the standards require that P>Q
, or the key will be rejected. However, the tool I used with Delphi (TPLockBox 2.0) didn't care about it.
Noting that above XML hex numbers are big endian, and watching your P and Q keys, see that you can run into troubles because D9<E2
, so P<Q
!!. Swapping your P and Q numbers before any calculation solves it, if I'm right (I'm absolutely NOT SURE about this point, could somebody confirm? Thnx)
Finally, convert all numbers to base64 and build the above XML structure.
STEP 2
With BouncyCastle, this is easier.
Download BouncyCastle.dll, copy to your project folder (or wherever), and add a reference to it into your VB project; now you will have a new "org" namespace and you can code:
Dim r As New RSACryptoServiceProvider()
' NOTE: substitute next string with above-like XML,
' or load it from a file or what you prefer:
r.FromXmlString("<RSAKeyValue><Modulus>vbBYUkGHX4YI1Rcovx+Ewz2OW........</RSAKeyValue>")
Dim key As Org.BouncyCastle.Crypto.AsymmetricCipherKeyPair = Org.BouncyCastle.Security.DotNetUtilities.GetRsaKeyPair(r)
' Export to a PEM file:
Dim fOut As New IO.StreamWriter("c:\keys.pem", False)
Dim pw As New Org.BouncyCastle.OpenSsl.PemWriter(fOut)
pw.WriteObject(key)
Hope it helps to all the noobs like me who sweated as I did while looking for the whole procedure.
Upvotes: 1
Reputation: 1
openssl/pem.h has following functions for reading/writing RSA keys (from a file) PEM_write_RSAPrivateKey PEM_read_PrivateKey
PEM_write_RSAPublicKey PEM_read_RSAPublicKey
if it still unclear how to use them just ask. I shall provide you with a few examples :-)
Upvotes: -1
Reputation: 2916
PEM-encoded RSA keys are basically the binary keys in the format described by PKCS#1 (RFC 3447), base-64 encoded and surrounded by an ASCII header and footer.
Note that PKCS#1 format requires that a private key include not just d, e, p, and q but also the other values used for Chinese Remainder Theorem (d mod (p-1), d mod (q-1), and (inverse of q) mod p). These are easily computed if you know p and q.
There's a bit more to it if the keys are encrypted, as you should then also have some PEM headers that describe the encryption.
There is sample code in the OpenSSL sources (though it's hardly commented at all, and quite hard to follow). You're better off reading the relevant RFCs, really, and checking your code against OpenSSL to make sure you have got it right.
Upvotes: 1