uses
JSON,
EncdDecd;
function Base64urlToBase64(Base64urlStr: String): String;
begin
Result := StringReplace(Base64urlStr,'_','/', [rfReplaceAll]);
Result := StringReplace(Result,'-','+', [rfReplaceAll]);
function JwkToPem(JWK: TJSONObject): String;
BinKey: TBytes;
begin
BinKey :=
[$30] + // ASN.1
[$77] + // Length of all following bytes (119 bytes)
[$02] + // Type (integer)
[$01] + // Length of integer (1 byte)
[$01] + // Value of integer (1)
[$04] + // Type (octet string)
[$20] + // Length of string (32 bytes)
DecodeBase64(Base64urlToBase64(JWK.Get('d').JsonValue.Value)) + // Private Key
[$A0] + // Tag 0
[$0A] + // Length of tag (10 bytes)
[$06] + // Type (Object ID)
[$08] + // Length of the Object ID (8 bytes)
[$2A, $86, $48, $CE, $3D, $03, $01, $07] + // - The object ID of the curve prime256v1
[$A1] + // Tag 1
[$44] + // Length of tag (68 bytes)
[$03] + // Type – Bit string
[$42] + // Length of the bit string (66 bytes)
[$00] + // ???
[$04] + // Uncompressed Public Key
DecodeBase64(Base64urlToBase64(JWK.Get('x').JsonValue.Value))+ // Public Key X coord
DecodeBase64(Base64urlToBase64(JWK.Get('y').JsonValue.Value)); // Public Key Y coord