
JWT(JSON Web令牌)和JOSE(JSON對象簽名和加密)規範套件的Delphi實現。該庫支持JWS(計劃支持JWE支持)與多種Jose算法的緊湊型序列化。

在Delphi 10西雅圖之前,HMAC-SHA算法通過Indy庫使用OpenSSL,因此為了生成令牌,您應該在服務器系統中擁有OpenSSL DLL。
在Delphi 10西雅圖或更新的Delphi版本中,HMAC算法也位於系統中。因此不需要OpenSSL。
HMAC-RSA(ECDA)算法必須使用OpenSSL,因此,如果您打算使用這些算法來簽名令牌,則必須下載和部署OpenSSL(在服務器上)。
請記住,客戶不必生成或驗證令牌(使用SHA或RSA),因此在客戶端上不需要OpenSSL DLL。
如果需要服務器上的OpenSL庫,則可以將軟件包直接下載到Indy的GitHub項目頁面(請記住,請始終更新到最新版本並匹配您的應用程序的位置)
Jose是一種標準,為任何內容的簽名和加密提供了一種通用方法。 Jose由幾個RFC組成:
| 演算法 | 支持 |
|---|---|
exp | ✔️ |
iat | ✔️ |
nbf | ✔️ |
aud | ✔️ |
iss | ✔️ |
jti | ✔️ |
typ | ✔️ |
TJOSEProducer和TJOSEProducerBuilder (Alias TJOSEProcess )類,以構建一個新的緊湊型令牌,並具有許多選項TJOSEConsumer和TJOSEConsumerBuilder類,以驗證以精細的粒度| 演算法 | 支持 |
|---|---|
None | ✔️不要使用它! ? |
HS256 | ✔️ |
HS384 | ✔️ |
HS512 | ✔️ |
RS256 | ✔️更新了! |
RS384 | ✔️更新了! |
RS512 | ✔️更新了! |
ES256 | ✔️新! ? |
ES384 | ✔️新! ? |
ES512 | ✔️新! ? |
ES256K | ✔️新! ? |
None算法漏洞的影響該圖書館已與Delphi 12雅典, Delphi 11 Alexandria , Delphi 10.4悉尼, Delphi 10.3 Rio , Delphi 10.2 Tokyo進行了測試,但是在某些工作中,它應該與DXE6及更高的工作進行編譯,但我沒有嘗試過或測試過這項工作,如果您成功地完成了這項任務,我將很高興創建您的工作分支!
該庫對外部庫/單位沒有依賴關係。
使用的Delphi單位:
只需將源路徑“源/公共”和源/何塞添加到您的delphi項目路徑,..您很高興!
使用boss install命令:
$ boss install github.com/paolo-rossi/delphi-jose-jwt要創建一個令牌,只需創建一個TJWT類的實例,然後設置屬性(Simels)。
構建JWT令牌(緊湊表示)的最簡單方法是使用IJOSEProducer接口:
uses
JOSE.Producer;
var
LResult: string;
begin
LResult := TJOSEProcess.New
.SetIssuer( ' Delphi JOSE Library ' )
.SetIssuedAt(Now)
.SetExpiration(Now + 1 )
.SetAlgorithm(LAlg)
.SetKey(TJOSEAlgorithmId.HS256)
.Build
.GetCompactToken
;
memoCompact.Lines.Add(LResult);
end ;序列化,進行序列化,驗證令牌的另一種方法是使用TJOSE實用程序類:
uses
JOSE.Core.JWT,
JOSE.Core.Builder;
var
LToken: TJWT;
LCompactToken: string;
begin
LToken := TJWT.Create;
try
// Token claims
LToken.Claims.Issuer := ' WiRL REST Library ' ;
LToken.Claims.Subject := ' Paolo Rossi ' ;
LToken.Claims.Expiration := Now + 1 ;
// Signing and Compact format creation
LCompactToken := TJOSE.SHA256CompactToken( ' my_very_long_and_safe_secret_key ' , LToken);
mmoCompact.Lines.Add(LCompactToken);
finally
LToken.Free;
end ;使用TJWT , TJWS和TJWK類,您可以更控制最終緊湊令牌的創建。
var
LToken: TJWT;
LSigner: TJWS;
LKey: TJWK;
LAlg: TJOSEAlgorithmId;
begin
LToken := TJWT.Create;
try
// Set your claims
LToken.Claims.Subject := ' Paolo Rossi ' ;
LToken.Claims.Issuer := ' Delphi JOSE Library ' ;
LToken.Claims.IssuedAt := Now;
LToken.Claims.Expiration := Now + 1 ;
// Choose the signing algorithm
case cbbAlgorithm.ItemIndex of
0 : LAlg := TJOSEAlgorithmId.HS256;
1 : LAlg := TJOSEAlgorithmId.HS384;
2 : LAlg := TJOSEAlgorithmId.HS512;
else LAlg := TJOSEAlgorithmId.HS256;
end ;
// Create your key from any text or TBytes
LKey := TJWK.Create(edtSecret.Text);
try
// Create the signer
LSigner := TJWS.Create(LToken);
try
// With this option you can have keys < algorithm length
LSigner.SkipKeyValidation := True;
// Sign the token!
LSigner.Sign(LKey, LAlg);
memoCompact.Lines.Add( ' Header: ' + LSigner.Header);
memoCompact.Lines.Add( ' Payload: ' + LSigner.Payload);
memoCompact.Lines.Add( ' Signature: ' + LSigner.Signature);
memoCompact.Lines.Add( ' Compact Token: ' + LSigner.CompactToken);
finally
LSigner.Free;
end ;
finally
LKey.Free;
end ;
finally
LToken.Free;
end ;
解開和驗證令牌很簡單。
您必須將密鑰和令牌緊湊型格式傳遞給TJOSE.Verify class函數
var
LKey: TJWK;
LToken: TJWT;
begin
// Create the key from a text or TBytes
LKey := TJWK.Create( ' my_very_long_and_safe_secret_key ' );
// Unpack and verify the token!
LToken := TJOSE.Verify(LKey, FCompactToken);
if Assigned(LToken) then
begin
try
if LToken.Verified then
mmoJSON.Lines.Add( ' Token signature is verified ' )
else
mmoJSON.Lines.Add( ' Token signature is not verified ' )
finally
LToken.Free;
end ;
end ;
end ;使用新的TJOSEConsumer很容易驗證令牌的主張。 TJOSEConsumer對像是使用Fluent接口使用TJOSEConsumerBuilder類構建的。
var
LConsumer: IJOSEConsumer;
begin
LConsumer := TJOSEConsumerBuilder.NewConsumer
.SetClaimsClass(TJWTClaims)
// JWS-related validation
.SetVerificationKey(edtConsumerSecret.Text)
.SetSkipVerificationKeyValidation
.SetDisableRequireSignature
// string-based claims validation
.SetExpectedSubject( ' paolo-rossi ' )
.SetExpectedAudience(True, [ ' Paolo ' ])
// Time-related claims validation
.SetRequireIssuedAt
.SetRequireExpirationTime
.SetEvaluationTime(IncSecond(FNow, 26 ))
.SetAllowedClockSkew( 20 , TJOSETimeUnit.Seconds)
.SetMaxFutureValidity( 20 , TJOSETimeUnit.Minutes)
// Build the consumer object
.Build();
try
// Process the token with your rules!
LConsumer.Process(Compact);
except
// (optionally) log the errors
on E: Exception do
memoLog.Lines.Add(E.Message);
end ;