grijjy / delphiopenssl Goto Github PK
View Code? Open in Web Editor NEWUsing OpenSsl with Delphi on all OS platforms for X.509 certificates and JWT
License: Other
Using OpenSsl with Delphi on all OS platforms for X.509 certificates and JWT
License: Other
I tested the example on Windows 64, and I get access Violation "Verify JSON Web Token"
JWT.VerifyWithPublicKey(JSONWebToken, PublicKeyBytes)
this is working correctly on Win32
Thank you
Hello,
I'm trying to compile the OpenSSL.Api_11.pas on LInux64 and I'm getting the following error.
I put the files on the same path as my .DPR
What am I doing wrong here?
files: libssl.so libcrypto.so
[DCC Error] E2597 C:\Program Files (x86)\Embarcadero\Studio\22.0\bin\ld-linux.exe: error: cannot find -lssl
C:\Program Files (x86)\Embarcadero\Studio\22.0\bin\ld-linux.exe: error: cannot find -lcrypto
C:\Fontes Sistemas\Placar Trumbica\Server Horse\Linux64\Debug\DCUs\OpenSSL.Api_11.o:OpenSSL.Api_11:function Openssl::Api_11::BIO_free(void*): error: undefined reference to 'BIO_free'
C:\Fontes Sistemas\Placar Trumbica\Server Horse\Linux64\Debug\DCUs\OpenSSL.Api_11.o:OpenSSL.Api_11:function Openssl::Api_11::BIO_new_mem_buf(void*, int): error: undefined reference to 'BIO_new_mem_buf'
C:\Fontes Sistemas\Placar Trumbica\Server Horse\Linux64\Debug\DCUs\OpenSSL.Api_11.o:OpenSSL.Api_11:function Openssl::Api_11::EVP_MD_CTX_create(): error: undefined reference to 'EVP_MD_CTX_new'
C:\Fontes Sistemas\Placar Trumbica\Server Horse\Linux64\Debug\DCUs\OpenSSL.Api_11.o:OpenSSL.Api_11:function Openssl::Api_11::EVP_MD_CTX_destroy(void*): error: undefined reference to 'EVP_MD_CTX_free'
C:\Fontes Sistemas\Placar Trumbica\Server Horse\Linux64\Debug\DCUs\OpenSSL.Api_11.o:OpenSSL.Api_11:function Openssl::Api_11::EVP_DigestUpdate(void*, void*, NativeUInt): error: undefined reference to 'EVP_DigestUpdate'
C:\Fontes Sistemas\Placar Trumbica\Server Horse\Linux64\Debug\DCUs\OpenSSL.Api_11.o:OpenSSL.Api_11:function Openssl::Api_11::EVP_DigestSignInit(void*, void**, void*, void*, void*): error: undefined reference to 'EVP_DigestSignInit'
C:\Fontes Sistemas\Placar Trumbica\Server Horse\Linux64\Debug\DCUs\OpenSSL.Api_11.o:OpenSSL.Api_11:function Openssl::Api_11::EVP_DigestSignFinal(void*, unsigned char*, NativeUInt&): error: undefined reference to 'EVP_DigestSignFinal'
C:\Fontes Sistemas\Placar Trumbica\Server Horse\Linux64\Debug\DCUs\OpenSSL.Api_11.o:OpenSSL.Api_11:function Openssl::Api_11::EVP_sha256(): error: undefined reference to 'EVP_sha256'
C:\Fontes Sistemas\Placar Trumbica\Server Horse\Linux64\Debug\DCUs\OpenSSL.Api_11.o:OpenSSL.Api_11:function Openssl::Api_11::EVP_PKEY_free(void*): error: undefined reference to 'EVP_PKEY_free'
C:\Fontes Sistemas\Placar Trumbica\Server Horse\Linux64\Debug\DCUs\OpenSSL.Api_11.o:OpenSSL.Api_11:function Openssl::Api_11::PEM_read_bio_PrivateKey(void*, void**, int (*)(char*, int, int, void*), void*): error: undefined reference to 'PEM_read_bio_PrivateKey'
Ty
Missing files :
Grijjy.inc
Grijjy.System
Grijjy.BinaryCoding
//Encrypt
function Encrypt_AEAD_AES_256_GCM(const AData, AKey, AIV, AAD: TBytes; out AEnCryptData,
ATag: TBytes): Boolean;
var
Ctx: PEVP_CIPHER_CTX;
Len: Integer;
DataLen: Integer;
begin
Result := False;
Len := 0;
DataLen := 0;
SetLength(AEnCryptData, 8192);
Ctx := EVP_CIPHER_CTX_new();
try
EVP_EncryptInit_ex(Ctx, EVP_aes_256_gcm(), nil, nil, nil);
// Set IV length if default 96 bits is not appropriate (12byte)
EVP_CIPHER_CTX_ctrl(Ctx, EVP_CTRL_GCM_SET_IVLEN, Length(AIV), nil);
EVP_EncryptInit_ex(Ctx, nil, nil, @akey[0], @aiv[0]);
if EVP_EncryptUpdate(Ctx, nil, @Len, @AAD[0], Length(AAD)) <> 1 then
Exit(False);
if EVP_EncryptUpdate(Ctx, @AEnCryptData[0], @Len, @AData[0], Length(AData)) <> 1 then
Exit(False);
DataLen := Len;
if EVP_EncryptFinal_ex(Ctx, @AEnCryptData[DataLen], @Len) <> 1 then
Exit(False);
DataLen := DataLen + Len;
SetLength(AEnCryptData, DataLen);
//get tag
SetLength(ATag, AUTH_TAG_LEN);
if EVP_CIPHER_CTX_ctrl(Ctx, EVP_CTRL_GCM_GET_TAG, AUTH_TAG_LEN, @ATag[0]) <> 1 then
Exit(False);
Result := True;
finally
EVP_CIPHER_CTX_free(Ctx);
end;
end;
//Decrypt
function Decrypt_AEAD_AES_256_GCM(const AData, AKey, AIV, AAD, ATag: TBytes;
out ADeCryptData: TBytes): Boolean;
var
Ctx: PEVP_CIPHER_CTX;
Len: Integer;
DataLen: Integer;
begin
Result := False;
if Length(AData) < AUTH_TAG_LEN then
Exit;
Len := 0;
DataLen := 0;
SetLength(ADeCryptData, 8192);
Ctx := EVP_CIPHER_CTX_new();
try
EVP_DecryptInit_ex(Ctx, EVP_aes_256_gcm, nil, nil, nil);
// Set IV length if default 96 bits is not appropriate (12byte)
EVP_CIPHER_CTX_ctrl(Ctx, EVP_CTRL_GCM_SET_IVLEN, Length(AIV), nil);
EVP_DecryptInit_ex(Ctx, nil, nil, @akey[0], @aiv[0]);
if EVP_DecryptUpdate(Ctx, nil, @Len, @AAD[0], Length(AAD)) <> 1 then
Exit(False);
if EVP_DecryptUpdate(Ctx, @ADeCryptData[0], @Len, @AData[0], Length(AData)) <> 1 then
Exit(False);
DataLen := Len;
//set tag
if EVP_CIPHER_CTX_ctrl(Ctx, EVP_CTRL_GCM_SET_TAG, AUTH_TAG_LEN, @ATag[0]) <> 1 then
Exit(False);
if EVP_DecryptFinal_ex(Ctx, @ADeCryptData[DataLen], @Len) <= 0 then
Exit(False);
DataLen := DataLen + Len;
SetLength(ADeCryptData, DataLen);
Result := True;
finally
EVP_CIPHER_CTX_free(Ctx);
end;
end;
In general, the tag parameter is attached after the ciphertext data, and the length is 16 bytes.
Hi Just thought I would add these 2 example functions to show the hard parts of converting an RSA PEM file to a JWK file as well as a JWK to a RSA PEM file.
For the missing TBase64URLURLEncoding class, have a look at
https://quality.embarcadero.com/browse/RSP-20316
which has instructions on how to create the class based on the System.NetEncoding.pas file included with Delphi.
// These declarations could be added to the OpenSsl.Api_11.pas file
function BN_bn2bin(ARet: PBIGNUM; ABin: Pointer): Integer; cdecl external LIB_CRYPTO name PREFIX + 'BN_bn2bin';
function BIO_ctrl(bp: PBIO; cmd: Integer; larg: longint; parg: Pointer): longint; cdecl external LIB_CRYPTO name PREFIX + 'BIO_ctrl';
function BIO_get_data(a: PBIO): Pointer; cdecl external LIB_CRYPTO name PREFIX + 'BIO_get_data';
function BIO_get_mem_data(a : PBIO; var pp : PAnsiChar) : Integer; cdecl external LIB_CRYPTO name PREFIX + 'BIO_get_mem_data';
function EVP_PKEY_get1_RSA(pkey: PEVP_PKEY): PRSA; cdecl external LIB_CRYPTO name PREFIX + 'EVP_PKEY_get1_RSA';
function PEM_read_bio_PUBKEY(ABIO: PBIO; x: PPEVP_PKEY; cb: TPEM_Password_Callback; u: Pointer ): PEVP_PKEY; cdecl external LIB_CRYPTO name PREFIX + 'PEM_read_bio_PUBKEY';
function PEM_write_bio_RSA_PUBKEY(bp: PBIO; x: PRSA): integer; cdecl external LIB_CRYPTO name PREFIX + 'PEM_write_bio_RSA_PUBKEY';
function PEM_write_bio_RSAPrivateKEY(bp: PBIO; x: PRSA): integer; cdecl external LIB_CRYPTO name PREFIX + 'PEM_write_bio_RSAPrivateKey';
function RSA_set0_key(RSA: PRSA; n: PBIGNUM; e: PBIGNUM; d: PBIGNUM): Integer; cdecl external LIB_CRYPTO name PREFIX + 'RSA_set0_key';
function RSA_set0_factors(RSA: PRSA; p: PBIGNUM; q: PBIGNUM): Integer; cdecl external LIB_CRYPTO name PREFIX + 'RSA_set0_factors';
function RSA_set0_crt_params(RSA: PRSA; dmp1: PBIGNUM; dmq1 :PBIGNUM; iqmp: PBIGNUM): Integer; cdecl external LIB_CRYPTO name PREFIX + 'RSA_set0_crt_params';
procedure RSA_get0_key(RSA: PRSA; var n: PBIGNUM; var e: PBIGNUM; var d: PBIGNUM); cdecl external LIB_CRYPTO name PREFIX + 'RSA_get0_key';
// Actual functions of interest
function CreatePublicJWKFromPEM(PEMString: AnsiString): string;
var
rr : PRSA;
ff : PBIO;
modul : PBIGNUM;
expon : PBIGNUM;
d : PBIGNUM;
nnBin : TArray<Byte>;
nnLen : Integer;
eeBin : TArray<Byte>;
eeLen : Integer;
base64URL : TBase64URLURLEncoding;
JSONkey : TJSONObject;
evp_key : PEVP_PKEY;
begin
base64URL := nil;
rr := nil;
ff := nil;
JSONkey := nil;
try
base64URL := TBase64URLURLEncoding.Create;
JSONkey := TJSONObject.Create;
ff := BIO_new_mem_buf(PAnsiChar(PEMString), Length(PEMString));
evp_key := PEM_read_bio_PUBKEY(ff, nil, nil, nil);
rr := EVP_PKEY_get1_RSA(evp_key);
RSA_get0_key(rr, modul, expon, d);
SetLength(nnBin, 1024);
SetLength(eeBin, 1024);
nnLen := BN_bn2bin(modul, nnBin);
eeLen := BN_bn2bin(expon, eeBin);
JSONkey.AddPair('e', base64URL.EncodeBytesToString(eeBin, eeLen));
JSONkey.AddPair('n', base64URL.EncodeBytesToString(nnBin, nnLen));
Result := JSONkey.ToJSON;
finally
BIO_free(ff);
EVP_PKEY_free(evp_key);
RSA_free(rr);
FreeAndNil(base64URL);
FreeAndNil(JSONkey);
end;
end;
function CreatePublicPEMFromJWK(json: TJSONObject): string;
var
rr : PRSA;
ff : PBIO;
modul : PBIGNUM;
expon : PBIGNUM;
nnBin : TArray<Byte>;
nnLen : Integer;
eeBin : TArray<Byte>;
eeLen : Integer;
base64URL : TBase64URLURLEncoding;
p : PAnsiChar;
res : Integer;
begin
base64URL := nil;
rr := nil;
ff := nil;
try
base64URL := TBase64URLURLEncoding.Create;
nnBin := base64URL.DecodeStringToBytes(json.Values['n'].Value);
eeBin := base64URL.DecodeStringToBytes(json.Values['e'].Value);
nnLen := Length(nnBin);
eeLen := Length(eeBin);
modul := BN_bin2bn(nnBin, nnLen, nil);
expon := BN_bin2bn(eeBin, eeLen, nil);
rr := RSA_new();
RSA_set0_key(rr, modul, expon, nil);
ff := BIO_new(BIO_s_mem());
PEM_write_bio_RSA_PUBKEY(ff, rr);
res := BIO_ctrl(ff, BIO_CTRL_INFO, 0, @p);
Result := Copy(p, 1, res);
finally
BIO_free(ff);
RSA_free(rr);
FreeAndNil(base64URL);
end;
end;
Grijjy.inc is missing. The project will not build. Thanks.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.