Jump to content
Eric Winfly

TSslCertTools for generate CSR

Recommended Posts

This is what i try before but my content i need to sign text like this

 

100000000120250815090926+000000000.25+000000000.50+000000005.75567891234RT00015678912340TQ0001FACOPE======================================================================================== 

 

And when i use your code you specify i obtain Base64Encoded String of length of 96 but her specification need a length of 88 (i use IcsBase64EncodeTB after SignDigest) ?

 

Now i have try :

 

	TSslCertTools *Tool = new TSslCertTools(NULL);
	AnsiString DataEnc, Digest, Secret;
	TBytes SigTB, DataTB = IcsStringToTBytes(Data), SecretTB, DigestTB;

	//Tool->PrivateKeyLoadFromPemFile("Certificat.pem");

	//DataEnc = IcsAsymSignDigest(Data, Tool->PrivateKey, Digest_sha256);
	//DataEnc = IcsBase64Encode(DataEnc);

	//DataEnc = IcsAsymSignDigest(Data, Tool->PrivateKey, Digest_sha256);
	//DataEnc = IcsBase64Encode(DataEnc);

	delete Tool;

	//return (DataEnc);

	//Configuration->FieldByName("CertificatKEY")->AsString;

	Secret = Configuration->FieldByName("CertificatKEY")->AsString;
	DataTB = IcsStringToTBytes(Data);
	SecretTB = IcsStringToTBytes(Secret);

	DigestTB = IcsHMACDigestTB(DataTB, SecretTB, Digest_sha512);
	DataEnc = IcsBase64EncodeTB(DigestTB);

With this last call i obtain 88 of length but the server tell me this is not sign with the FingerPrint of the last cert ???

 

Note : i put Digest_sha512 because this give me 88 of length !

Share this post


Link to post

Also im not sure if ICS Library digital signature with format p1363 or ASN, i also need to create a p1363 sign ?

 

Share this post


Link to post

Sha256 and Sha512 give different length digests, and HMAC is not using a private key.  Private keys are not strings.  

 

Digests are binary, there are lots of ways of converting binary to text, variations of bas64, hex, etc.  You need to work which version gives you the length you need.  

 

ASN is the binary format of X509 certificates, never heard of p1363.  Signing gives a digest, nothing more. 

 

Angus

 

Share this post


Link to post
2 hours ago, Angus Robertson said:

Sha256 and Sha512 give different length digests, and HMAC is not using a private key.  Private keys are not strings.  

 

Digests are binary, there are lots of ways of converting binary to text, variations of bas64, hex, etc.  You need to work which version gives you the length you need.  

 

ASN is the binary format of X509 certificates, never heard of p1363.  Signing gives a digest, nothing more. 

 

Angus

 

So 

IcsAsymSignDigest

Return only sign digest base on asn.1, i need to convert to ieee p1363 ? Nothing do this in Ics Library ?

Share this post


Link to post

Thanks Angus i found and it work now, there is my code if you need in futur :

 

String SignData(String Data)
{
	TSslCertTools *Tool = new TSslCertTools(NULL);
	AnsiString DataEnc;
	TBytes SignTB, DataTB;

	Tool->PrivateKeyLoadFromText(Configuration->FieldByName("CertificatKey")->AsString, "");

	DataTB = IcsStringToTBytes(Data);
	SignTB = IcsAsymSignDigestTB(DataTB, Tool->PrivateKey, Digest_sha256);
	SignTB = ConvertASNToP1363(SignTB);

	DataEnc = IcsBase64EncodeTB(SignTB);
	delete Tool;

	return (DataEnc);
}

TBytes ConvertASNToP1363(TBytes SignatureTB)
{
	TBytes bSignature;
	bSignature.Length = 64;

	TBytes bR = ExtraireR(SignatureTB);
	TBytes bS = ExtraireS(SignatureTB);

	System::Move(&bR[0], &bSignature[0], 32);
	System::Move(&bS[0], &bSignature[32], 32);

	return(bSignature);
}

TBytes ExtraireR(TBytes Signature)
{
	int debutR = (Signature[1] & 0x80) != 0 ? 3 : 2;
	int longueurR = Signature[debutR + 1];

	TBytes bR;
	bR.Length = 32;

	TBytes bTemp;
	bTemp.Length = longueurR;

	System::Move(&Signature[debutR + 2], &bTemp[0], longueurR);

	if (bTemp.Length == 33)
		System::Move(&bTemp[1], &bR[0], 32);
	else if (bTemp.Length <= 32)
		System::Move(&bTemp[0], &bR[32 - bTemp.Length], bTemp.Length);

	return(bR);
}

TBytes ExtraireS(TBytes Signature)
{
	int debutR = (Signature[1] & 0x80) != 0 ? 3 : 2;
	int longueurR = Signature[debutR + 1];
	int debutS = debutR + 2 + longueurR;
	int longueurS = Signature[debutS + 1];

	TBytes bS;
	bS.Length = 32;

	TBytes bTemp;
	bTemp.Length = longueurS;

	System::Move(&Signature[debutS + 2], &bTemp[0], longueurS);

	if (bTemp.Length == 33)
		System::Move(&bTemp[1], &bS[0], 32);
	else if (bTemp.Length <= 32)
		System::Move(&bTemp[0], &bS[32 - bTemp.Length], bTemp.Length);

	return(bS);
}

Eric

Share this post


Link to post

Adding the three functions to convert the ASN.1 signature to the simpler IEEE version would be good, but I need Delphi code for ICS. 

 

Angus

 

Share this post


Link to post
4 hours ago, Angus Robertson said:

Adding the three functions to convert the ASN.1 signature to the simpler IEEE version would be good, but I need Delphi code for ICS. 

 

Angus

 

I have done in my source code and i send to you for algorytm. It in C++ but i think its usefull for you also its fully tested and debugged :) Cheers !

Share this post


Link to post

Now i need to Encrypt with RSA public Key but the function StrEncRsa make fault on libcrypto-3.dll with the sample IcsPemTool this is normal

 

i take a look at source code and this function make a first call to EncryptPublicRSA with OutBuf = nil this could be the problem ?

 

i also try to make call directly to EncryptPublicRSA but C++ dont want to find a good declaration of this func ??

Share this post


Link to post

Those ICS encryption functions were written 15 years ago by another developer, I've never used them not aware anyone else has either, so untested. 

 

But you may have hit a change in latest version, make sure OverbyteDefs.inc has {$DEFINE OpenSSL_Deprecated}

 

Angus

 

Share this post


Link to post
52 minutes ago, Angus Robertson said:

Those ICS encryption functions were written 15 years ago by another developer, I've never used them not aware anyone else has either, so untested. 

 

But you may have hit a change in latest version, make sure OverbyteDefs.inc has {$DEFINE OpenSSL_Deprecated}

 

Angus

 

Thanks, you know if i can use it with a pem file contening only cert with only public key ?

 

The gouv only returning Cert with public key ?

 

He use X509Certificat to add to Windows Store and after he reload it for calling RSA Encrypt with PublicKey but whatever i search over internet and all openssl pkeyutl cmd i try always tell me 

 

openssl pkeyutl -encrypt -inkey CertificatPSI.pem -pubin -in pass.txt -out pass.enc
Could not find private key of public key from CertificatPSI.pem
pkeyutl: Error loading key

 

Im afraid about all about certificat :classic_blink:

Edited by Eric Winfly

Share this post


Link to post
1 hour ago, Eric Winfly said:

Thanks, you know if i can use it with a pem file contening only cert with only public key ?

 

The gouv only returning Cert with public key ?

 

He use X509Certificat to add to Windows Store and after he reload it for calling RSA Encrypt with PublicKey but whatever i search over internet and all openssl pkeyutl cmd i try always tell me 

 

openssl pkeyutl -encrypt -inkey CertificatPSI.pem -pubin -in pass.txt -out pass.enc
Could not find private key of public key from CertificatPSI.pem
pkeyutl: Error loading key

 

Im afraid about all about certificat :classic_blink:

Angus could you please find me a solution to Encrypt RSA Text from public key with Ics because i always receive libcrypto-3.dll access violation. I have try your new version 9.5 with deprectec_openssl activate but this not work, i have update openssl dll to the lastest 2.5.2 but always have acces violation ?

 

If i need to use an older version for Ics or OpenSsl for EncryptRsaPublic work, tell me, im very bad and i need to produce this project for the next week :classic_wacko:

 

Many thanks for all, Eric !

Share this post


Link to post

I'll test PemTools to make sure RSA encryption is not broken in V9,5, the source code clearly states it needs a rewrite to work properly with OpenSSL 3, unless  {$DEFINE OpenSSL_Deprecated} is used. 

 

Angus

 

Share this post


Link to post

What is your version of your openssl you run because with brand new compiled ics 9.5 and openssl 3.5.2.0 i always receive 

 

EAccessViolation in module libcrypto-3.dll Read of adresse 0000000C ?

 

If i go in debug mode on pemtool and go directly to the func 

    EncryptPublicRSA(PubKey, PAnsiChar(S), Length(S), nil, Len, Padding); // THIS CALL WORK for obtain the length
    SetLength(Result, Len);
    if EncryptPublicRSA(PubKey, PAnsiChar(S), Length(S), PAnsiChar(Result), Len, Padding) then // BUT THIS ONE AccessViolation 

The first call for the length work but the other for obtain the buffer make accessviolation ?

Share this post


Link to post

Have you added the define as requested and rebuilt all the packages so the old RSA functions are loaded?  Check the pointer to RSA_public_encrypt is not nil. 

 

I am adding a better sample for the encryption stuff, but this is a busy week, end of the month stuff. 

 

Angus

 

Share this post


Link to post
1 hour ago, Eric Winfly said:

The first call for the length work but the other for obtain the buffer make accessviolation ?

May i ask what is the problem with using RSA_public_encrypt directly instead of this unknown EncryptPublicRSA, which might be wrong in its parameters.

 

Try to use RSA_private_encrypt directly, just check the return value, as it is not a Boolean, and the size/length is per documentation is RSA_size(rsa), and don't forget to trim, as these functions be called with extra length and the result is the exact length.

From OverbyteIcsLIBEAY.pas

    RSA_private_decrypt :                    function(flen: Integer; from: PAnsiChar; to_: PAnsiChar; rsa: PRSA; padding: Integer): Integer; cdecl = nil;
    RSA_public_encrypt :                     function(flen: Integer; from: PAnsiChar; to_: PAnsiChar; rsa: PRSA; padding: Integer): Integer; cdecl = nil;

 

@Angus Robertson While the above two functions should be what OP is asking for, this unit misses the other pair

    RSA_private_encrypt :                    function(flen: Integer; from: PAnsiChar; to_: PAnsiChar; rsa: PRSA; padding: Integer): Integer; cdecl = nil;
    RSA_public_decrypt :                     function(flen: Integer; from: PAnsiChar; to_: PAnsiChar; rsa: PRSA; padding: Integer): Integer; cdecl = nil;

 

Sources

https://docs.openssl.org/1.0.2/man3/RSA_public_encrypt/

https://docs.openssl.org/1.0.2/man3/RSA_private_encrypt/

Share this post


Link to post

If you read my message properly, you'll see I specifically mentioned RSA_public_encrypt as the functions ICS has used for 15 years. But it is deprecated and no longer loaded by the latest ICS.  

 

If you are going to make comments about the ICS library, which I understand you do not actually use, please do some minimal research first.  Some of your comments are useful, many just confuse real ICS users. 

 

Angus

 

  • Like 1

Share this post


Link to post

Yes i change the depreciate define and rebuilt all but me i use CBIcsInstallVclFmx.groupproj this is good ? Or i need to rebuilt some delphi project ?

Share this post


Link to post

Found the problem with encryption and decryption, the RSA key is blank, possible because of an internal change in OpenSSL at some point and OpenSSL dies rather than giving a sensible error message.  

 

In function EncryptPublicRSA (and the other), change Ics_Ssl_EVP_PKEY_GetKey to EVP_PKEY_get1_RSA and it should work again. 

 

I'll fix it properly shortly with new tests in the JOSE sample, the E stands for encryption, but currently it does no encryption.  I'll also update it for new APIs, but that won't be this week.  

 

Angus

 

Share this post


Link to post
2 hours ago, Kas Ob. said:

May i ask what is the problem with using RSA_public_encrypt directly instead of this unknown EncryptPublicRSA, which might be wrong in its parameters.

 

Try to use RSA_private_encrypt directly, just check the return value, as it is not a Boolean, and the size/length is per documentation is RSA_size(rsa), and don't forget to trim, as these functions be called with extra length and the result is the exact length.

From OverbyteIcsLIBEAY.pas


    RSA_private_decrypt :                    function(flen: Integer; from: PAnsiChar; to_: PAnsiChar; rsa: PRSA; padding: Integer): Integer; cdecl = nil;
    RSA_public_encrypt :                     function(flen: Integer; from: PAnsiChar; to_: PAnsiChar; rsa: PRSA; padding: Integer): Integer; cdecl = nil;

 

@Angus Robertson While the above two functions should be what OP is asking for, this unit misses the other pair


    RSA_private_encrypt :                    function(flen: Integer; from: PAnsiChar; to_: PAnsiChar; rsa: PRSA; padding: Integer): Integer; cdecl = nil;
    RSA_public_decrypt :                     function(flen: Integer; from: PAnsiChar; to_: PAnsiChar; rsa: PRSA; padding: Integer): Integer; cdecl = nil;

 

Sources

https://docs.openssl.org/1.0.2/man3/RSA_public_encrypt/

https://docs.openssl.org/1.0.2/man3/RSA_private_encrypt/

I try this and same error AccessViolation $0000000C in libcrypto-3.dll i think this dll is not loaded ?

Share this post


Link to post
2 hours ago, Angus Robertson said:

Found the problem with encryption and decryption, the RSA key is blank, possible because of an internal change in OpenSSL at some point and OpenSSL dies rather than giving a sensible error message.  

 

In function EncryptPublicRSA (and the other), change Ics_Ssl_EVP_PKEY_GetKey to EVP_PKEY_get1_RSA and it should work again. 

 

I'll fix it properly shortly with new tests in the JOSE sample, the E stands for encryption, but currently it does no encryption.  I'll also update it for new APIs, but that won't be this week.  

 

Angus

 

Nice Angus its work now, very thanks !

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×