0

I use: Delphi JOSE and JWT Library and OpenSSL libraries version 1.0.2

uses
 ...
  JSON,
  System.DateUtils,
  JOSE.Core.JWT,
  JOSE.Core.JWS,
  JOSE.Core.JWK,
  JOSE.Core.JWA;
...

procedure TForm1.Button1Click(Sender: TObject);
var
  LToken: TJWT;
  LSigner: TJWS;
  LKey: TJWK;
  LAlg: TJOSEAlgorithmId;
  LPrivateKey, LPublicKey, LClaims, LHeader: TJSONObject;
  LKeys: TKeyPair;
begin
  LToken := TJWT.Create;

  LPrivateKey := TJSONObject.Create;
  LPrivateKey.AddPair('kty', 'EC');
  LPrivateKey.AddPair('alg', 'ES256');
  LPrivateKey.AddPair('crv', 'P-256');
  LPrivateKey.AddPair('x', 'sDbcYT8HzBk1tUl849ZHrhpIn8ZV7HfD1DwYdsP1ip0');
  LPrivateKey.AddPair('y', 'EWodfKWQ6oE0ppyi7tRO_61BgAQsZyDjDGj9kLZiUts');
  LPrivateKey.AddPair('d', 'Rwyv99W3GnfjYbI0X-b5Umhvh88oRCKQkPxiwCPVGgg');

  LKeys := TKeyPair.Create;
  LKeys.PrivateKey.Key := LPrivateKey.ToString;

  LClaims := TJSONObject.Create;
  LClaims.AddPair('email', 'myemail@mail.com');
  LClaims.AddPair('aud', 'usr');
  LClaims.AddPair('iat', TJSONNumber.Create(DateTimeToUnix(TTimeZone.Local.ToUniversalTime(now))));
  LClaims.AddPair('jti', '0x'+IntToHex(Random(High(Integer))));

  LHeader := TJSONObject.Create;
  LHeader.AddPair('alg','ES256');
  LHeader.AddPair('kid', '1');
    
  LToken.Header.JSON := LHeader;
  LToken.Claims.JSON := LClaims;
    
  LAlg := TJOSEAlgorithmId.ES256;

  LSigner := TJWS.Create(LToken);
  LSigner.SkipKeyValidation := True;

  // Sign the token!
  LSigner.Sign(LKeys.PrivateKey, LAlg);

  Memo1.Lines.Add('Header: ' + LSigner.Header);
  Memo1.Lines.Add('Payload: ' + LSigner.Payload);
  Memo1.Lines.Add('Signature: ' + LSigner.Signature);
  Memo1.Lines.Add('Compact Token: ' + LSigner.CompactToken);
end;

The error occurs when signing a token:

 Exception class ESignException with message '[ECDSA] Unable to load private key:
 error:0906D06C:lib(9):func(109):reason(108)'

I suspect that the private key needs to be submitted in a different format. In the Delphi JOSE and JWT Library examples, the private key is stored in a PM-file and has the following format:

-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIFzS3/5bCnrlpa4902/zkYzUQF6E2D8pazgnKu4smhpQoAoGCCqLSM49
AwEHoUQDQgBEqTjyg2z65i+zbyUXW8BQ+K87DNsICRaEH7Fy7Nm3MseXy9ItSCQU
VeJbtO6kYUA00mx7bKoC1sx5sbtFExnYPQ==
-----END EC PRIVATE KEY-----

It looks like base64, but when I convert my key to base64, the library returns the same error. I would be glad to any advice.

HeathRow
  • 117
  • 1
  • 8
  • You can use TJWK.Create(MyKey) to sign you JWT – Bosshoss Mar 04 '21 at 16:31
  • @Bosshoss `JWK:= TJWK.Create(LPrivateKey.ToString);` and then `LSigner.Sign(JWK, LAlg);`? Doesn't matter, same error. – HeathRow Mar 04 '21 at 17:21
  • Running the command `openssl errstr 0906D06C` gives `error:0906D06C:PEM routines:PEM_read_bio:no start line`. OpenSSL is trying to read a PEM file but the file it has been given doesn't have the expected start line, i.e. `-----BEGIN WHATEVER PRIVATE KEY-----` – Matt Caswell Mar 04 '21 at 19:25
  • What format is your key in? How did you create it? – Matt Caswell Mar 04 '21 at 19:26
  • You need to use open ssl to create your cert file – Bosshoss Mar 04 '21 at 20:36
  • @MattCaswell I get the private and public keys from the api service. The service provide keys in simple text format (JSON-object in my code). If only PEM-format keys is required to sign a token, then the main question is, how do I convert my text-key to a PEM format? – HeathRow Mar 05 '21 at 12:50
  • Can you show a sample format that you receive them in (obviously only showing example keys - not real ones)? – Matt Caswell Mar 05 '21 at 16:25
  • @MattCaswell Real test key, (already deleted from account): `{"kty":"EC","alg":"ES256","crv":"P-256","x":"sDbcYT8HzBk1tUl849ZHrhpIn8ZV7HfD1DwYdsP1ip0","y":"EWodfKWQ6oE0ppyi7tRO_61BgAQsZyDjDGj9kLZiUts","d":"Rwyv99W3GnfjYbI0X-b5Umhvh88oRCKQkPxiwCPVGgg"}` – HeathRow Mar 05 '21 at 16:51
  • It's example of what I need, but on python code - https://github.com/bitzlato/api-auth-examples/blob/develop/python/connect.py – HeathRow Mar 05 '21 at 17:00
  • 1
    I can't help you with the python code. But it looks like you have a key in JWK format. You need it in PEM or DER format to be readable by OpenSSL. The target format is described in RFC5915: https://tools.ietf.org/html/rfc5915 – Matt Caswell Mar 05 '21 at 22:52
  • 1
    @MattCaswell You're right. Was needed convertation JWK to PEM format. Now it work, thank you! I found online converter - https://keytool.online/ – HeathRow Mar 07 '21 at 15:04

0 Answers0