mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-15 05:49:12 +02:00
* Example for RSA signing
This commit is contained in:
parent
bce88f2e2b
commit
efe414f128
144
packages/fcl-web/examples/jwt/signrs256.lpr
Normal file
144
packages/fcl-web/examples/jwt/signrs256.lpr
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
{$mode objfpc}
|
||||||
|
{$h+}
|
||||||
|
uses jsonparser, dateutils, sysutils, fppem, fpjwt, fprsa, fphashutils, fpjwarsa;
|
||||||
|
|
||||||
|
Type
|
||||||
|
// The claims we want to sign in our JWT.
|
||||||
|
// You can skip this class and just use TClaims if the standard claims are sufficient
|
||||||
|
|
||||||
|
TMyClaims = Class(TClaims)
|
||||||
|
private
|
||||||
|
FAdmin: Boolean;
|
||||||
|
FName: string;
|
||||||
|
Published
|
||||||
|
Property Name : string Read FName Write FName;
|
||||||
|
Property admin : Boolean Read FAdmin Write FAdmin;
|
||||||
|
end;
|
||||||
|
|
||||||
|
// A JWT that uses our claims
|
||||||
|
TMyJWT = Class(TJWT)
|
||||||
|
Function CreateClaims : TClaims; override;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function TMyJWT.CreateClaims: TClaims;
|
||||||
|
begin
|
||||||
|
Result:=TMyClaims.Create;
|
||||||
|
end;
|
||||||
|
|
||||||
|
// Read the private/public key data
|
||||||
|
// In reality you will read this from a file.
|
||||||
|
|
||||||
|
procedure GetTestPEM(out aPrivateKeyPEM, aPublicKeyPEM: string);
|
||||||
|
|
||||||
|
const
|
||||||
|
// generated with
|
||||||
|
// openssl genrsa -out private.pem 2048
|
||||||
|
PrivateKeyPem =
|
||||||
|
'-----BEGIN RSA PRIVATE KEY-----'#10+
|
||||||
|
'MIIEpQIBAAKCAQEAvkRfGW8psCZ3G4+hBA6W/CR/FHhBLB3k3QLypamPbRFlFBxL'#10+
|
||||||
|
'tOK2NblBybY22vUiMLZbb5x8OoOj/IhOrJAlTqhtbTWLy/0K3qbG09vLm8V40kEK'#10+
|
||||||
|
'8/p0STrp3UmsxHNkccj9MRSKk7pOyEvxSCY6K5JGK1VTsMuDCS7DCYk6Vqr3zjX7'#10+
|
||||||
|
'qedF1PVM+Z5t0B+f//kt3oBETNlic4IooEpG/PN2GUQ0oZpa16DDtfgGu7wT3X3Q'#10+
|
||||||
|
'EZFWLJYQTvGc82NpachBIUvqNdIt1npbK38MXU4IPHVrSN/HdK2nQPSMLdKnTV+E'#10+
|
||||||
|
'h/HcxpfjBjarg+VjgDqlmqJ9bkosOVn35vsg8wIDAQABAoIBAQCZxVwujB7fFFdS'#10+
|
||||||
|
'2QPC6Z+w7DYgbwgNBaP/0vAUXzNhbJuKY0v0Rv4H8U9wHGm9EDyvrdG8JHZqPBX+'#10+
|
||||||
|
'dJNQ97aPGaRGjO4M0NdGFve+JXcqz6/UDWkywYnV3V1A0NhmdPQK2et3DSjqN7qQ'#10+
|
||||||
|
'OoAoVWzR5gf74Zwf2Hpwo3BRdqzFeUYVDOH7e7q1SOf2QeU54kVUG21saJR0wsyH'#10+
|
||||||
|
'oSX8BMU2kmg1Un8ET4FM5xEwhdTZzgFTJVZhc6EfOKVbQt6cKmW3aER3c9vR7M3l'#10+
|
||||||
|
'N6Oq73vqrfmy+jFMwz1SoPObQQ7UAnr7YUowaX0AzxHpYm/afyVm+Toym0qWGrrY'#10+
|
||||||
|
'MY/l+vNRAoGBAOsi72pJj30ApfVbSpx8/8QIpweLbEgAD+Ssd41Kgc4O/N7azB61'#10+
|
||||||
|
'RjzSOs1BGhpAZNU6muAAbucm9EssfG5WTAjIM2W2LVuZXXEVXqEGkIymPz9NGugf'#10+
|
||||||
|
'JaCWLaoibmwHkKa+ZV9kDwasmx/VkbAfAbRWaz49ejdrMmkpCW77lYjHAoGBAM8m'#10+
|
||||||
|
'PVJWvFhQrB21xQGSWKd5iSUn2V92gICeDoORqfVtt/UPOaDT915KzXPh4bJeOwg6'#10+
|
||||||
|
'Kkx5wX6UwaNSRH39loDSY1rsBYioV8bxW0BpBvEJG7KXRbBvxzr0+TJkCHgmGMns'#10+
|
||||||
|
'dhePYUcriCaqpQi1yzf201oLTZ6PlJxkmHQobXJ1AoGBAIgWPg576InmWCa64WHU'#10+
|
||||||
|
'joq8nz8kmFTLhGdK0h56IspJrlyksUKMk8wbuGCW7y6GWlV2h7BhT86Eoxrm8lVB'#10+
|
||||||
|
'qNvkUqrpVzMOfiA2x//WNs7QYQaX75ysejCI+oDfUJ1Be5yl0TH2TSQFvfoctycB'#10+
|
||||||
|
'qxDee08YcaWlaxWl5InRHeh9AoGABm3XZWDPw6XtUZa8oIncOoZpHUAZXP8eid9d'#10+
|
||||||
|
'7/NrZPScyvxH+5fYi5Kiwb/280Q9bMnxWiJFQRp40ArTmV1veFwPPVkp6s3eu4vu'#10+
|
||||||
|
'GxenYX+43lgXj5xIgKntugSkxqXYCxxNpfmLOVw+g4S0Torl3bzJXngPVqZ6JEhy'#10+
|
||||||
|
'+tfuXakCgYEA19/JCD/5pVPJtwyDDAYnUUESK+JfBPq1cTbsxcOq01mp5ntsqR4y'#10+
|
||||||
|
'dtOAmxMASvsqud3XIM5fO5m3Jpl1phiGhCw4nvVLcYzVWxYY+oWoeCSyECgu5tmT'#10+
|
||||||
|
'Fo8vn4EEXCkEAA2YPiEuVcrcYsWkLivCTC19lJDfUNMmpwSdiGz/tDU='#10+
|
||||||
|
'-----END RSA PRIVATE KEY-----'#10;
|
||||||
|
|
||||||
|
PublicKeyPem =
|
||||||
|
'-----BEGIN PUBLIC KEY-----'#10+
|
||||||
|
'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvkRfGW8psCZ3G4+hBA6W'#10+
|
||||||
|
'/CR/FHhBLB3k3QLypamPbRFlFBxLtOK2NblBybY22vUiMLZbb5x8OoOj/IhOrJAl'#10+
|
||||||
|
'TqhtbTWLy/0K3qbG09vLm8V40kEK8/p0STrp3UmsxHNkccj9MRSKk7pOyEvxSCY6'#10+
|
||||||
|
'K5JGK1VTsMuDCS7DCYk6Vqr3zjX7qedF1PVM+Z5t0B+f//kt3oBETNlic4IooEpG'#10+
|
||||||
|
'/PN2GUQ0oZpa16DDtfgGu7wT3X3QEZFWLJYQTvGc82NpachBIUvqNdIt1npbK38M'#10+
|
||||||
|
'XU4IPHVrSN/HdK2nQPSMLdKnTV+Eh/HcxpfjBjarg+VjgDqlmqJ9bkosOVn35vsg'#10+
|
||||||
|
'8wIDAQAB'#10+
|
||||||
|
'-----END PUBLIC KEY-----';
|
||||||
|
|
||||||
|
begin
|
||||||
|
aPrivateKeyPEM:=PrivateKeyPem;
|
||||||
|
aPublicKeyPEM:=PublicKeyPem;
|
||||||
|
end;
|
||||||
|
|
||||||
|
Procedure CreateKeyAndJWT(out Key : TJWTKey; Out JWT : TJWT);
|
||||||
|
|
||||||
|
begin
|
||||||
|
Key:=TJWTKey.Create('mysecretkey');
|
||||||
|
JWT:=TMyJWT.Create;
|
||||||
|
JWT.JOSE.alg:='none';
|
||||||
|
JWT.JOSE.typ:='JWT';
|
||||||
|
JWT.Claims.sub:='1234567890';
|
||||||
|
JWT.Claims.iat:=1516239022;
|
||||||
|
(JWT.Claims as TMyClaims).Name:='John Doe';
|
||||||
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
aInput, aPrivateKeyPEM, aPublicKeyPEM: String;
|
||||||
|
Key: TJWTKey;
|
||||||
|
VerifyResult,JWT : TJWT;
|
||||||
|
Signer: TJWTSigner;
|
||||||
|
NewDER: TBytes;
|
||||||
|
RSAPublic: TX509RSAPublicKey;
|
||||||
|
RSAPrivate: TX509RSAPrivateKey;
|
||||||
|
|
||||||
|
begin
|
||||||
|
CreateKeyAndJWT(Key,JWT);
|
||||||
|
GetTestPEM(aPrivateKeyPEM, aPublicKeyPEM);
|
||||||
|
|
||||||
|
// header
|
||||||
|
jwt.JOSE.alg:=TJWTSignerRS256.AlgorithmName;
|
||||||
|
|
||||||
|
// claims
|
||||||
|
jwt.Claims.exp:=DateTimeToUnix(Now+10);
|
||||||
|
jwt.Claims.iss:='FPC JWT';
|
||||||
|
|
||||||
|
// load private key from pem
|
||||||
|
Key.AsBytes:=PemToDER(APrivateKeyPem,_BEGIN_RSA_PRIVATE_KEY,_END_RSA_PRIVATE_KEY);
|
||||||
|
X509RsaPrivateKeyInitFromDER(RSAPrivate,Key.AsBytes);
|
||||||
|
NewDER:=RSAPrivate.AsDER;
|
||||||
|
if (length(Key.AsBytes)<>length(NewDER)) or
|
||||||
|
not CompareMem(@Key.AsBytes[0],@NewDER[0],length(NewDER)) then
|
||||||
|
Raise exception.Create('TX509RSAPrivateKey.AsDER does not match!');
|
||||||
|
|
||||||
|
// sign
|
||||||
|
Signer:=TJWTSignerRS256.Create;
|
||||||
|
try
|
||||||
|
aInput:=Signer.AppendSignature(JWT,Key);
|
||||||
|
finally
|
||||||
|
Signer.Free;
|
||||||
|
end;
|
||||||
|
|
||||||
|
Writeln('Our JWT Token: ',aInput);
|
||||||
|
|
||||||
|
// load public key from pem
|
||||||
|
Key.AsBytes:=PemToDER(APublicKeyPem,_BEGIN_PUBLIC_KEY,_END_PUBLIC_KEY);
|
||||||
|
X509RsaPublicKeyInitFromDER(RSAPublic,Key.AsBytes);
|
||||||
|
NewDER:=RSAPublic.AsDER;
|
||||||
|
if (length(Key.AsBytes)<>length(NewDER)) or
|
||||||
|
not CompareMem(@Key.AsBytes[0],@NewDER[0],length(NewDER)) then
|
||||||
|
Raise exception.Create('TX509RSAPublicKey.AsDER does not match');
|
||||||
|
|
||||||
|
// verify our generated token. This generates a new JWT
|
||||||
|
VerifyResult:=TMyJWT.ValidateJWT(aInput,Key);
|
||||||
|
if VerifyResult=Nil then
|
||||||
|
Raise Exception.Create('No verify resultn, verification failed!');
|
||||||
|
end.
|
Loading…
Reference in New Issue
Block a user