Converti questa firma digitale php in Delphi

Vorrei riscrivere questa function di firma digitale php nel codice Delphi.

function SaySig() { $privKeyFilePath = "c:\temp\myrsakey.pem"; $data = "sign this string"; $fp = fopen($privKeyFilePath, "r"); $priv_key = fread($fp, 8192); fclose($fp); $privatekeyid = openssl_get_privatekey($priv_key); openssl_sign($data, $signature, $privatekeyid, OPENSSL_ALGO_SHA1); openssl_free_key($privatekeyid); $sig = base64_encode($signature); echo "<br>"; echo "Signature:".$sig."<br><br>"; } 

Non mi interessa quale componente viene utilizzato (lockbox, DelphiOpenSSL , Chilkat Crypt ActiveX, ecc.). Ho provato tutti questi senza successo; il che mi fa pensare che sto facendo qualcosa di fondamentalmente sbagliato.

La mia chiave è stata generata in quanto tale:

openssl req -x509 -nodes -days 365 -newkey rsa: 1024 -sha1 -subj "/ C = US / ST = CA / L = Mountain View / CN = www.mycompany.com" -keyout myrsakey.pem -out c: \ temp \ myrsacert.pem

Il contenuto della chiave (non preoccuparti – ne genererò uno nuovo):

—– BEGIN RSA chiave privata —– MIICXgIBAAKBgQCqsR7s4X74LfTiLv1PP6Yn0SBpGBtbzkBSQ95E2b9Haa3Qtf0a KjDJpZLMwXC / IrSP7K2Gxbl2cZotT19GVgw6PcYPTBBWX2gJoVrnQZP8uPdlGAgS plODP55R9f4F0KzIpE6d + dpTGfJ1wysFqYN8fxtlu8K7YO / Mh8tNzN5VOQIDAQAB AoGBAIvCvRyeQlU5Y + JzMSvbZNQDUrNabsRL67SwJ2VemVUCvbQ / 3v62fv4M2VdY KFYIN6oE08yfRw0pVWE2NT + lIxqSQx7 + qv84Y7duqT7155wpCFj + a / 6pYyNTFNFi 5wiTnN13eyHNgKxZm7QcMH67T / noTgz0LoT5p54ynmfNcjyBAkEA3DCEQ6Dm2xYH Nhk3 + 7sNEVklN20zNqyYvrCunNLAiLioF1jDApdfcT8YtVd29L7tH1ZdJYG5DXJ8 Bs7eKLGekQJBAMZzy0Q7LZHdWQxSRi7wy0eq6SqZMqi0pb9VPuXjWG1y + rtRr1vV vyMaGz4rcE7mkbq / nkn + AQXc30GOj3GE8CkCQQCMDVwDfBN6pL8 / fLjsJ + S + 9RnD 8HRTwWKCX / UgkLif / fwEpZOcUVYGvSBlL9XdBJfkh9VFZwaidABJgEk0Tw3RAkBd 6pjMnpDvUeh9e0Y5mr0pGookHcIqsuspxEby9od3rI1aLsslU9 + T1hwEbPxGarmW vj0MAUgspR2G4deiqn4ZAkEAnWxV7NhtVPLs5Y2ZYeHz7ipdcSL4 / keLW4PwKerF 7LJj4s7 / 6ZqnHA6Z0yhCcziflYQArWt1ViLMIYZ8grr5Kg == —– END chiave privata RSA —–

E l'output appare come tale:

jcIIsr145dTwDrT8g4jb2HZ5FP5UL6 / 9mK7hF6hC2lCZGlM0W4QqFqytghWaU0w3Z6JkMVUlxxWtQ2R + vWQVB0F3htAtbVZkiA67x0zor + zmpClBIazmfVJlng4sG1R7CCUZ0gGhdm4JMc08VsWU25utudcG6inpl whQiZgefW0 =

Potrebbe sembrare che sto chiedendo a qualcuno di "fare il mio lavoro". Ma mi sono battuto per un po 'senza successo. Grazie.

Qualcuno ha richiesto di postare parte del mio codice. Di seguito sono alcune delle cose che ho provato ..

 function TMainWeb.sign(mstring: String): string; var mPrivateKey: TLbRSAKey; LbRSASSA1: TLbRSASSA; begin LbRSASSA1:= TLbRSASSA.create(nil); LbRSASSA1.PrivateKey.LoadFromFile('C:\temp\myrsakey.der'); LbRSASSA1.HashMethod := TRSAHashMethod(hmSHA1); LbRSASSA1.SignString(mString); result := LbRSASSA1.Signature.IntStr; end; function TMainWeb.sign1(mstring: String): string; var LbDSA1: TLbDSA; mPrivateKey: TLbRSAKey; begin mPrivateKey := TLbRSAKey.Create(aks1024); mPrivateKey.LoadFromFile('C:\temp\myrsakey.der'); LbDSA1 := TLbDSA.create(application); lbDSA1.PrivateKey.Assign(mPrivateKey); LbDSA1.SignString(mString); end; function TMainWeb.Sign2(mString: String): string; var signer: TMessageSigner; begin signer := TMessageSigner.Create; signer.LoadPrivateKey('C:\temp\myrsakey.pem'); signer.PlainMessage := mString; signer.MIMESign; result := signer.SignedMessage; end; 

Prova questo.
Non rivendico il suo codice perfetto (!) Ma lo compila 🙂 e dà lo stesso risultato che hai citato. Utilizza l'API OpenSSL di M Ferrante che hai menzionato sopra. Un sacco di cose che normalmente si dovrebbe fare una volta all'avvio – come caricare la chiave privata, InitSSL ecc. Io uso il JCL Jedi per le cose di base64 – è più semplice.
Anche alcuni di questi aspetti sono un po 'strani (usa TBytes where PChar farebbe etc etc) come ho originariamente scritto usando le mie intestazioni di API Delphi 2010 modificate ma poi mi sono reso conto che stavi usando D2007 e TEncoding non era disponibile e alcune mod erano necessarie.
(SignStringToBase64 è la chiamata principale, proprio in fondo alla list)

 uses libeay32, jclmime; const LIBEAY_DLL_NAME = 'libeay32.dll'; // These aren't defined in the original libeay32.pas file procedure EVP_MD_CTX_init(ctx: PEVP_MD_CTX); cdecl; external LIBEAY_DLL_NAME; function EVP_MD_CTX_cleanup(ctx: PEVP_MD_CTX): integer; cdecl; external LIBEAY_DLL_NAME; procedure InitSSL; begin OpenSSL_add_all_algorithms; OpenSSL_add_all_ciphers; OpenSSL_add_all_digests; ERR_load_crypto_strings; // Seed the pseudo-random number generator // This should be something a little more "random"! RAND_load_file('c:\windows\paint.exe', 512); end; procedure FinalizeSSL; begin EVP_cleanup; end; function GetSSLErrorMessage: string; const BUFF_SIZE = 128; // OpenSSL docs state should be >= 120 bytes var err: TBytes; begin SetLength(err, BUFF_SIZE); ERR_error_string(ERR_get_error, @err[0]); result := string(err); end; function RSALoadPrivateKey(const AFileName, APassPhrase: string): PRSA; var bp: pBIO; fn, pp: PAnsiChar; pk: PRSA; begin fn := PAnsiChar(AnsiString(AFileName)); pp := PAnsiChar(AnsiString(APassPhrase)); bp := BIO_new(BIO_s_file()); BIO_read_filename(bp, fn); pk := nil; result := PEM_read_bio_RSAPrivateKey(bp, pk, nil, pp); if result = nil then raise Exception.Create('Private key failure.' + GetSSLErrorMessage); end; function LoadPrivateKey(const AFileName, APass: string): PEVP_PKEY; var rkey: PRSA; begin rkey := RSALoadPrivateKey(AFileName, APass); result := EVP_PKEY_new; EVP_PKEY_assign(result, EVP_PKEY_RSA, rkey); end; procedure CleanUpKey(AKey: PEVP_PKEY); begin if (AKey <> nil) then begin EVP_PKEY_free(AKey); // The OpenSSL docs state that the related rsa key will also // be freed when the parent key is freed end; end; function EVPSign(ASource: TBytes; const APrivateKey: PEVP_PKEY): TBytes; var keysize: integer; ks: cardinal; ctx: EVP_MD_CTX; begin keysize := EVP_PKEY_size(APrivateKey); SetLength(result, keysize); EVP_MD_CTX_init(@ctx); try EVP_SignInit(@ctx, EVP_sha1); EVP_SignUpdate(@ctx, @ASource[0], Length(ASource)); EVP_SignFinal(@ctx, @result[0], ks, APrivateKey); SetLength(result, ks); finally EVP_MD_CTX_cleanup(@ctx); end; end; function Base64EncodeBytes(Input: TBytes): string; var b64: TBytes; begin SetLength(b64, jclMime.MimeEncodedSizeNoCRLF(Length(Input))); jclMime.MimeEncodeNoCRLF(Input[0], Length(Input), b64[0]); result := string(b64); end; function SignStringToBase64(const AText: string): string; var key: PEVP_PKEY; src, enc: TBytes; begin InitSSL; try key := LoadPrivateKey('c:\temp\priv-key.pem', ''); try SetLength(src, Length(AText)); CopyMemory(@src[0], @AText, Length(AText)); enc := EVPSign(src, key); result := Base64EncodeBytes(enc); finally CleanUpKey(key); end; finally FinalizeSSL; end; end;