Shrinavat 16 Posted 12 hours ago Hey everyone, I’m trying to reverse engineer a piece of JavaScript code found within an HTML file. It has this get_cookie_spsc_encrypted_part function, which contains an RSA private key embedded within a comment, and also an encrypted string. It uses some JavaScript crypto lib, KJUR.crypto.Cipher.decrypt, to decrypt this string. Here’s the Javascript code: function get_cookie_spsc_encrypted_part() { let func = function () {/*-----BEGIN RSA PRIVATE KEY----- MIICXAIBAAKBgQDFoP5AJIv1KFGRpv/Uw7drFXjWbZG6wNsO7P58ocZIcxyKGU6u TgXw8N1IvTmd9yXRSdcb2fCWB7J/QUQDJQ3YuuXSOQCVOdi8Wy9UoZ5jNdqtZ6CM CvnK/v4Wy38ZhrB0CRkeiuyjmUdfQhe8mh3pE3iFBusYd1TVCxQt3VBkqQIDAQAB AoGAaYBaeo+ID6YodWL7a+/XeNkLmxz/EP1nc/5clNgf7AlXkPmVoUORtGBBIVWy 7ntDuwh6Ryn/X3hYd8q1riAX1UwVuUduOENmgyzmO1rRIoB/17vzYwVMYOB2h+qb xEqjg4dUfk/1occyDwpehWel+1NIgvQLNYLcn2JXxkAyrMkCQQD37+3Y8sjYxwAp giIClsCjrla73cS/QwzArGEnOjBs86LyzCc0pNzmP2OD0a9VlD3k6dMnhT2Oj+2k nZs8dUlHAkEAzA4/mQeFvdiKIkzUBECn3w9Ylu2IfpKnQt/0EFUENxS9ONZ1jj4p zDBfZosgwnE1GiECELM3R/6Pzl+uIGrajwJBALm5HG3az+CykMiHFnrh+kOiII5x vSOYUkEx30THLecvSeyeSPACXwaKjTz9IV31wbdsACQmhsn3vogFF3feU5kCQARP 9MYeI5RshBbPeteQKjwLjfq6kFzkaoZ+RyElOs6TMKCH37oe1DFNgGahYBLb45xm wC1sLCnoVk+tM/fZaj8CQGQyIlxwbgNBBdV3wnmtX9yPDflOsjpo3FuBMOu3nZAD KEpmTXFgdwP4oMMbCmDvH3dav92LE5JN1cPik9z0Piw= -----END RSA PRIVATE KEY----- */}; let pem = func.toString().match(/[^]*\/\*([^]*)\*\/\}$/)[1]; return KJUR.crypto.Cipher.decrypt("82a4fa1da959701407ae4a80b48c0dca57d68fb5e54df1794418b03ba43ef9022328e4be4011ffbeb74d9d22769634a21537ba32788342f8abe6cfddc22512a39373ea2488af389740ac4f93699da92fcd86895c64bd6760a5aea27e172052947361177f3674ec68c52480744a75163c892556ec526387c92c0b50ab0b3a4ea5", KEYUTIL.getKey(pem)); } I’ve managed to replicate the decryption in C# using System.Security.Cryptography. Here’s the C# code: using System.Text.RegularExpressions; using System.Security.Cryptography; var pemKey = Regex.Match(html, "-----BEGIN RSA PRIVATE KEY-----[\\s\\S]*?-----END RSA PRIVATE KEY-----").Value; var encryptedDataHex = Regex.Match(html, @"KJUR.crypto.Cipher.decrypt\(""(.*)""").Groups[1].Value; using var rsa = RSA.Create(); rsa.ImportFromPem(pemKey); var decryptedData = rsa.Decrypt(Convert.FromHexString(encryptedDataHex), RSAEncryptionPadding.Pkcs1); // Perform Decryption Now, I’m trying to do the same in Delphi, and I’d like to use TurboPower LockBox 3. Unfortunately, the official documentation seems to be offline. I am struggling to understand how to use LockBox 3, or other suitable free libraries for this purpose. Could anyone provide some Delphi code examples and guidance on how to do the RSA decryption, using LockBox or any other free library? Any help would be greatly appreciated! Here's my code: program RSA_test; {$APPTYPE CONSOLE} uses System.SysUtils, System.Classes, System.RegularExpressions, uTPLb_Codec, uTPLb_CryptographicLibrary, uTPLb_BaseNonVisualComponent, uTPLb_Signatory, uTPLb_Constants, uTPLb_Asymetric, uTPLb_RSA_Engine, uTPLb_OpenSSL; const HTML = '<html><head><script>function get_cookie_spsc_encrypted_part() {' + ' let func = function () {/*-----BEGIN RSA PRIVATE KEY-----' + 'MIICXAIBAAKBgQDFoP5AJIv1KFGRpv/Uw7drFXjWbZG6wNsO7P58ocZIcxyKGU6u' + 'TgXw8N1IvTmd9yXRSdcb2fCWB7J/QUQDJQ3YuuXSOQCVOdi8Wy9UoZ5jNdqtZ6CM' + 'CvnK/v4Wy38ZhrB0CRkeiuyjmUdfQhe8mh3pE3iFBusYd1TVCxQt3VBkqQIDAQAB' + 'AoGAaYBaeo+ID6YodWL7a+/XeNkLmxz/EP1nc/5clNgf7AlXkPmVoUORtGBBIVWy' + '7ntDuwh6Ryn/X3hYd8q1riAX1UwVuUduOENmgyzmO1rRIoB/17vzYwVMYOB2h+qb' + 'xEqjg4dUfk/1occyDwpehWel+1NIgvQLNYLcn2JXxkAyrMkCQQD37+3Y8sjYxwAp' + 'giIClsCjrla73cS/QwzArGEnOjBs86LyzCc0pNzmP2OD0a9VlD3k6dMnhT2Oj+2k' + 'nZs8dUlHAkEAzA4/mQeFvdiKIkzUBECn3w9Ylu2IfpKnQt/0EFUENxS9ONZ1jj4p' + 'zDBfZosgwnE1GiECELM3R/6Pzl+uIGrajwJBALm5HG3az+CykMiHFnrh+kOiII5x' + 'vSOYUkEx30THLecvSeyeSPACXwaKjTz9IV31wbdsACQmhsn3vogFF3feU5kCQARP' + '9MYeI5RshBbPeteQKjwLjfq6kFzkaoZ+RyElOs6TMKCH37oe1DFNgGahYBLb45xm' + 'wC1sLCnoVk+tM/fZaj8CQGQyIlxwbgNBBdV3wnmtX9yPDflOsjpo3FuBMOu3nZAD' + 'KEpmTXFgdwP4oMMbCmDvH3dav92LE5JN1cPik9z0Piw=' + '-----END RSA PRIVATE KEY-----' + '*/};' + ' let pem = func.toString().match(/[^]*\\/\\*([^]*)\\*\\/\\}$/)[1];' + ' return KJUR.crypto.Cipher.decrypt("82a4fa1da959701407ae4a80b48c0dca57d68fb5e54df1794418b03ba43ef9022328e4be4011ffbeb74d9d22769634a21537ba32788342f8abe6cfddc22512a39373ea2488af389740ac4f93699da92fcd86895c64bd6760a5aea27e172052947361177f3674ec68c52480744a75163c892556ec526387c92c0b50ab0b3a4ea5", KEYUTIL.getKey(pem));' + '} </script></head><body></body></html>'; var PEMKey, EncryptedDataHex, DecryptedData: string; Codec: TCodec; CryptoLib: TCryptographicLibrary; Signatory: TSignatory; EncryptedBytes, DecryptedBytes: TBytes; MemStream: TMemoryStream; StringStream: TStringStream; begin try Codec := TCodec.Create(nil); CryptoLib := TCryptographicLibrary.Create(nil); Signatory := TSignatory.Create(nil); try with TRegEx.Match(HTML, '-----BEGIN RSA PRIVATE KEY-----[\s\S]*?-----END RSA PRIVATE KEY-----') do if Success then PEMKey := Value; with TRegEx.Match(HTML, 'KJUR\.crypto\.Cipher\.decrypt\("(.*)\"') do if Success then EncryptedDataHex := Groups[1].Value; // Convert base64-string to bytes EncryptedBytes := TNetEncoding.Base64.DecodeStringToBytes(EncryptedDataHex); // Setup encryption components Codec.CryptoLibrary := CryptoLib; Codec.StreamCipherId := 'native.RSA'; Codec.ChainModeId := 'native.CBC'; Codec.AsymetricKeySizeInBits := 1024; // ??? StringStream := TStringStream.Create(PEMKey); try Signatory.Codec := Codec; Signatory.LoadKeysFromStream(StringStream, [partPrivate]); // !!! raised exception class EReadError with message 'Stream read error' finally StringStream.Free; end; // Decrypt data MemStream := TMemoryStream.Create; try MemStream.WriteBuffer(EncryptedBytes[0], Length(EncryptedBytes)); MemStream.Position := 0; Codec.DecryptStream(MemStream, MemStream); // In-place decryption // Get decrypted data SetLength(DecryptedBytes, MemStream.Size); MemStream.Position := 0; MemStream.ReadBuffer(DecryptedBytes[0], MemStream.Size); DecryptedData := TEncoding.UTF8.GetString(DecryptedBytes); finally MemStream.Free; end; finally Codec.Free; CryptoLib.Free; Signatory.Free; end; except on E: Exception do WriteLn(E.ClassName, ': ', E.Message); end; ReadLn; end. Share this post Link to post