Jump to content
steve faleiro

How to convert JWK to PEM format in Delphi?

Recommended Posts

Posted (edited)

I have this RSA public key in JWK format: 

   

Quote

{
      "kty": "RSA",
      "e": "AQAB",
      "kid": "55c188a83546fc188e51576ba72836e0600e8b73",
      "n": "q0CrF3x3aYsjr0YOLMOAhEGMvyFp6o4RqyEdUrnTDYkhZbcud-fJEQafCTnjS9QHN1IjpuK6gpx5i3-Z63vRjs5EQX7lP1jG8Qg-CnBdTTLw4uJi7RmmlKPsYaO1DbNkFO2uEN62sOOzmJCh1od3CZXI1UYH5cvZ_sLJaN2A4TwvUTU3aXlXbUNJz_Hy3l0q1Jjta75NrJtJ7Pfj9tVXs8qXp15tZXrnbaM-AI0puswt35VsQbmLwUovFFGeToo5q2c_c1xYnV5uQYMadANekGPRFPM9JZpSSIvH0Lv_f15V2zRqmIgX7a3RcmTnr3-w3QNQTogdy-MogxPUdRbxow"
}

 

I need to convert it to PEM format. This website does the conversion, but I need to do it in Delphi. I have read this StackOverflow post that asks the same question but the answer provided does not work with my data because the "d", "x" and "y" JSON keys are missing in my input data (meaning my data is a different format). 

 

In that same SO post, Arnaud Bouchez suggested using code from the Mormot2 library to do the work, and I've downloaded that library from GitHub but I can't seem to figure out how to start using it for this scenario. 

I have also had a look and installed "Delphi JOSE and JWT Library" but cannot figure out how to write the code to do what I need. I believe that this library may be able to do what I need.

 

I've also posted this question on StackOverflow here: https://stackoverflow.com/questions/78073930/how-to-convert-jwk-to-pem-format-in-delphi

 

Edited by steve faleiro

Share this post


Link to post

Hi,

 

I see no one answered you here, so i am not going to answer because i don't have a complete answer, and will explain why this will not be like the way it happened with EC JWK, and shouldn't be.

 

PEM (Privacy Enhancement for Internet Electronic Mail) originally from https://www.rfc-editor.org/rfc/rfc1421 which had been updated few times and the last RFC is https://www.rfc-editor.org/rfc/rfc7468

With PEM and EC is easier and simpler then RSA keys to encode because (while both parameters are INTEGERS) but RSA parameters are encoded as BITSTRING then encapsulate the integers then list them as an array, this combined type has bit length not bytes, on top of that the length for fields with ASN.1 has its own standard which is not in byte, word, and dword, but again it is on own bit level, so the code to generate the headers for any type that can arbitrary is complex, unlike the case you mentioned with EC as the length private key or public key for such prime is fixed in length because the parameters are integers from a field predefined either by the named curve or by another parameter in case the curve is not named (not the case with SO example), again here the field size will be BITSTRING, but this is irrelevant here, in EC x and y are the public key which is a simple point in a field, while d is the scalar in that named field representing the private key.

 

Back to RSA and its parameters, in your public key there is e and n ,

e is the exponent which is in most cases have one of two values (3 or 65537), 3 is not recommended, there are other small primes like (5, 17..) but i never saw RSA key with one of them.

n is a prime, and this is the problem with the size if case the integer is not using the highest bit.

Both must have their length convoyed by PEM in bits not in bytes, is your case the length is 2048, but is there a guarantee the generator of your key ? i  don't know.

 

My suggestion is to not try something like the SO example, i use proprietary library and never tried open source for such key with manually loading the parameters, but it should be doable easily, ICS or mormot(2) should/might do it, but i can't answer how easily it can be, as you should load the e and n from the JWK and feed them to some class in these library or use the raw functions of OpenSSL, after that OpenSSL will give you a right formatted PEM file/data.

Both libraries i believe have do support JWK, so there a chance your need is very simple of load and pass to a class or something then save.

 

Sorry can't help more.

 

ps : if you want to replicate what have being done with SO example then you need the ASN1 parser, but again i don't recommend it, it might fail.

https://lapo.it/asn1js/

and here is it with the PEM EC key from SO 

https://lapo.it/asn1js/#MHcCAQEEIEcMr_fVtxp342GyNF_m-VJob4fPKEQikJD8YsAj1RoIoAoGCCqGSM49AwEHoUQDQgAEsDbcYT8HzBk1tUl849ZHrhpIn8ZV7HfD1DwYdsP1ip0Rah18pZDqgTSmnKLu1E7_rUGABCxnIOMMaP2QtmJS2w

Switch the "Definitions:" in that page to "PKCS#8 encrypted private key" for consistency in naming.

Share this post


Link to post

ICS has various Jose and PEM functions that will read and create Json Web Keys.

 

IcsJoseJWKGetPKey reads the Json text and saves the key as type TX509Base.

 

TX509Base has methods to save certificates, private and public keys in numerous formats. 

 

What do you want to do with the public key?  This may be better discussed in the ICS support forum .

 

Angus

 

 

  • Like 1

Share this post


Link to post

Angus, 

 

Thanks for pointing me in the right direction. I will try writing code to accomplish this with ICS and if I face difficulty I will post on the ICS forum.

 

-Steve 

Share this post


Link to post

Look at the OverbyteIcsJoseTst sample which has a button that decodes your JWK using the function I mentioned, and displays it raw, while the OverbyteIcsPemTools sample does certificate and key conversions.

 

ICS V9.1 has a new TX509Base method X509PubKeyTB that returns the public key in DER that can be used to compare with another public key or converted to Base64 which is PEM.

 

Angus

 

Share this post


Link to post
Posted (edited)
11 hours ago, Angus Robertson said:

Look at the OverbyteIcsJoseTst sample which has a button that decodes your JWK using the function I mentioned, and displays it raw, while the OverbyteIcsPemTools sample does certificate and key conversions.

 

ICS V9.1 has a new TX509Base method X509PubKeyTB that returns the public key in DER that can be used to compare with another public key or converted to Base64 which is PEM.

 

Angus

 

Hi Angus, 


Thanks for your expert response. It has helped me achieve what I needed ie. to encode the JWK key to PEM format. The code in the `OverbyteIcsJoseTst` sample with ICS V9.1 allowed to save the key to PEM format by adding the following line:

FVerifyPKey.PublicKeySaveToPemFile('c:\temp\out.pem');

Everything good now (I think!). Thanks again.
 

Edited by steve faleiro

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×