
Реализация Delphi JWT (JSON Web Token) и спецификации Hose (JSON Object Fighting and Encryption). Эта библиотека поддерживает компактные сериализации JWS (поддержка JWE) с несколькими алгоритмами Хосе.

До Delphi 10 Seattle алгоритм HMAC-SHA использует OpenSSL через библиотеку Indy, поэтому для создания токена вы должны иметь DLL OpenSSL в вашей серверной системе.
В Delphi 10 Seattle или более новых версиях Delphi алгоритм HMAC также находится в системе. Hash Unit, поэтому OpenSSL не нужен.
Алгоритм HMAC-RSA (ECDSA) использует обязательно OpenSSL, поэтому, если вы планируете использовать эти алгоритмы для подписи вашего токена, вам нужно загрузить и развернуть OpenSSL (на сервере).
Пожалуйста, имейте в виду, что клиент не должен генерировать или проверять токен (используя SHA или RSA), поэтому на стороне клиента нет необходимости в DLL OpenSSL.
Если вам нужна библиотека OpenSSL на сервере, вы можете загрузить пакет непосредственно на страницу проекта Indy GitHub (имейте в виду, что всегда обновлять последнюю версию и соответствовать Bitness приложения)
Хосе - это стандарт, который обеспечивает общий подход к подписанию и шифрованию любого контента. Хосе состоит из нескольких RFC:
| Алгоритмы | Поддерживается |
|---|---|
exp | ✔ |
iat | ✔ |
nbf | ✔ |
aud | ✔ |
iss | ✔ |
jti | ✔ |
typ | ✔ |
TJOSEProducer и TJOSEProducerBuilder (псевдоним TJOSEProcess ) для создания нового компактного токена со многими вариантами TJOSEConsumer и TJOSEConsumerBuilder для проверки токена с тонкой гранулярностью| Алгоритмы | Поддерживается |
|---|---|
None | ✔ Не используйте это! ? |
HS256 | ✔ |
HS384 | ✔ |
HS512 | ✔ |
RS256 | ✔ Обновлено! |
RS384 | ✔ Обновлено! |
RS512 | ✔ Обновлено! |
ES256 | ✔ Новое! ? |
ES384 | ✔ Новое! ? |
ES512 | ✔ Новое! ? |
ES256K | ✔ Новое! ? |
NoneЭта библиотека была протестирована с Delphi 12 Athens , Delphi 11 Alexandria , Delphi 10.4 Sydney , Delphi 10.3 Rio , Delphi 10.2 Tokyo , но с какой -то работой она должна компилировать с DXE6 и выше , но я не пробовал или не проверил это, если вам удастся в этой задаче, я буду рад создать ветвь вашей работы!
Эта библиотека не имеет зависимости от внешних библиотек/единиц.
Используются подразделения Delphi:
Просто добавьте исходный путь «Source/Common» и Source/Jose »в ваш путь проекта Delphi, и ... вы готовы к работе!
Используя команду boss install :
$ boss install github.com/paolo-rossi/delphi-jose-jwt Чтобы создать токен, просто создайте экземпляр класса TJWT и установите свойства (претензии).
Самый простой способ построить токен 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 построен с утилитом утилиты TJOSEConsumerBuilder с использованием интерфейса Fluent.
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 ;