I am sending down some information from a server that is using OpenSSL::Cipher to encrypt the data using AES-256-CBC. I am receiving the data in an application that is coded in Delphi XE8 and attempting to decrypt the data using TPLB 3 OpenSSL. From everything I have tried I have all of the information matching, the key, the iv etc), but I still get an error or junk data when attempting to decrypt. I am assuming that there is something I am missing with TPLB 3 setup/config to get it to decrypt properly, but I can't for the life of me figure it out. Any help is much appreciated.
Delphi Decrypting
function TLicenseReload.Decode(L, K, I: string): string;
var
cdec: TOpenSSL_Codec;
s: string;
sOut,
sIn: TStream;
begin
Result := '';
cdec := TOpenSSL_Codec.Create(nil);
sIn := TStringStream.Create;
sout := TStringStream.Create;
try
sIn.Write(L, length(L));
sIn.Position := 0;
cdec.SetKey(TEncoding.Default.GetBytes(K));
cdec.SetIV(TEncoding.Default.GetBytes(I));
cdec.Cipher := cipher_aes_256_cbc;
cdec.PaddingScheme := {padNone;//}padPKCS;
//cdec.LibName := 'libeay32.dll'; //toggled on and off to attempt to decrypt correctly
//cdec.LibPath := ExtractFilePath(Application.Exename); //toggled on and off to attempt to decrypt correctly
//cdec.RequiredVersion := '1.0.1.7'; //toggled on and off to attempt to decrypt correctly
cdec.isLoaded := true; //receive an access violation if this is not set
cdec.Decrypt(sOut, sIn);
//s := sOut.DataString; //was using TStringStream but wasn't working so switched to TStream
sOut.ReadBuffer(s[1], sOut.Size - sOut.Position);
result := s;
finally
sOut.Free;
sIn.Free;
cdec.Free;
end;
end;
Ruby Encrypting
begin
unless loc.nil?
cip = OpenSSL::Cipher.new('AES-256-CBC')
cip.encrypt
cip.key = Digest::SHA1.hexdigest(loc.l_hash[0..31].upcase).upcase
lic_iv = cip.random_iv
lic_iv = Base64.encode64(lic_iv)
enc_lic_date = cip.update(loc.licensed_through.to_s + ':' + loc.customer.purchased.to_s) + cip.final
enc_lic_date = Base64.encode64(enc_lic_date)#.encode('utf-8')
#enc_lic_date << cip.final
end
rescue StandardError => e
error_message = e.to_s
puts e.to_s
end
EDIT:
I went back and double checked everything (basically starting over). I have confirmed that the bytes being encrypted on the server (before they are Base64 encdoed) are the same as the bytes that are being decrypted (post Base64 decoding) on the client. However, I am still getting "junk" out.
Updated (cluttered) Delphi Decrypting
function TLicenseReload.DecodeLicense(L, K, I: string): string;
var
cdec: TOpenSSL_Codec;
s: string;
sOut,
sIn: TStringStream;
x,
y: TBytes;
z: string;
begin
Result := '';
cdec := TOpenSSL_Codec.Create(nil);
sIn := TStringStream.Create;
sout := TStringStream.Create;
try
SetLength(x, Length(K));
SetLength(y, Length(DecodeBase64(I)));
//SetLength(z, Length(DecodeBase64(L)));
x := TEncoding.UTF8.GetBytes(K);
y := DecodeBase64(I);
//z := string(DecodeBase64(L));
//sIn.WriteString(z);//, length(z));
sIn.WriteData(DecodeBase64(L), length(DecodeBase64(L)));
sIn.Position := 0;
//cdec.SetKey(TEncoding.UTF8.GetBytes(unbaseit(K)));
//cdec.SetIV(TEncoding.UTF8.GetBytes(unbaseit(I)));
cdec.SetKey(TEncoding.UTF8.GetBytes(K));
cdec.SetIV(DecodeBase64(I));
cdec.Cipher := cipher_aes_256_cbc;
cdec.PaddingScheme := padNone;//}padPKCS;
//cdec.LibName := 'libeay32.dll';
//cdec.LibPath := ExtractFilePath(Application.Exename);
//cdec.RequiredVersion := '1.0.1.7';
cdec.isLoaded := true;
cdec.Decrypt(sOut, sIn);
s := sOut.DataString;
//sOut.ReadBuffer(s[1], sOut.Size - sOut.Position);
result := s;
finally
sOut.Free;
sIn.Free;
cdec.Free;
end;
end;
EDIT 2 TPLB3 has two options for padding, None or PKCS. With None set, I get junk out. With PKCS set I get an "OpenSSL encryption error". The encoding on the results does not seem to matter, it is still junk.
I was able to get the encrypted data sent down to decrypt. I ended up using the functions and unit from this post. I had to modify them slightly, and updated a couple of the function calls to fit my needs, which I will post below.
I had looked at the post before and could not get it to work and gave up and went back to TPLB3. After banging my head against a wall for hours and hours and researching and digging around on the net, I was so close with TPLB3 and I just could not get the expected results. So at a suggestion from a co-worker, I looked at this again and realized that when I tried it the first time I was indeed passing bytes from the wrong encoded strings, which I found and tracked down in my quest to get TPLB3 to work. Once I plugged this back in, it took a little tweaking and updating (the updating just in case the old functions were ever removed) to get it to work properly for my specific case.