Eric Winfly 1 Posted August 19 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
Eric Winfly 1 Posted August 19 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
Angus Robertson 662 Posted Wednesday at 08:00 AM 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
Eric Winfly 1 Posted Wednesday at 10:03 AM 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
Angus Robertson 662 Posted Wednesday at 10:29 AM Have a read at https://blog.yaakov.online/ecdsa-signatures-openssl-vs-net/ might give you a few clues. I'm not planning any signing changes in ICS at the moment, the next release is weeks overdue. Angus Share this post Link to post
Eric Winfly 1 Posted Wednesday at 09:19 PM 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
Angus Robertson 662 Posted Thursday at 08:02 AM 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
Eric Winfly 1 Posted Thursday at 12:37 PM 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
Eric Winfly 1 Posted Friday at 04:29 PM 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
Angus Robertson 662 Posted Friday at 05:50 PM 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
Eric Winfly 1 Posted Friday at 06:41 PM (edited) 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 Edited Friday at 06:46 PM by Eric Winfly Share this post Link to post
Eric Winfly 1 Posted Friday at 08:39 PM 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 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 Many thanks for all, Eric ! Share this post Link to post
Angus Robertson 662 Posted Saturday at 08:23 AM 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
Eric Winfly 1 Posted 8 hours ago 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
Angus Robertson 662 Posted 7 hours ago 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
Kas Ob. 152 Posted 6 hours ago 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
Angus Robertson 662 Posted 5 hours ago 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 1 Share this post Link to post
Eric Winfly 1 Posted 4 hours ago 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
Angus Robertson 662 Posted 4 hours ago 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
Eric Winfly 1 Posted 4 hours ago 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
Eric Winfly 1 Posted 2 hours ago 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