Recent

Author Topic: How to decript a string using RSA Private Key ??  (Read 1249 times)

garlar27

  • Hero Member
  • *****
  • Posts: 652
How to decript a string using RSA Private Key ??
« on: February 10, 2022, 11:32:21 pm »
I need to decrypt a string using RSA Private Key but I couldn't find an FPC example. By the way I don't know what FPC is using now LibreSSL or OpenSSL.

So i searched for a Delphi example and tried see if I could adapt it to the lazarus fpc\3.2.2\source\packages\openssl\src\openssl.pas

The one I found was this https://github.com/ddlencemc/RSA-via-OpenSSL-libeay32 and some function had slightly different names and changes in param types and other where completely missing probably because differences in SSL version.

The code I'm interested to port is this one (RSAOpenSSL.pas):
Code: Pascal  [Select][+][-]
  1. procedure TRSAOpenSSL.PrivateDecrypt(var aRSAData: TRSAData);
  2. var
  3.   rsa: pRSA;
  4.   out_: AnsiString;
  5.   str, data: PAnsiChar;
  6.   len: Integer;
  7.   b64, mem: pBIO;
  8.   size: Integer;
  9.   err: Cardinal;
  10. begin
  11.   LoadSSL;
  12.   FPrivateKey := LoadPrivateKey;
  13.   //FPrivateKey := LoadPrivateKeyFromString(''); // Load PrivateKey from including ansistring;
  14.   if FPrivateKey = nil then
  15.   begin
  16.     err := ERR_get_error;
  17.     repeat
  18.       aRSAData.ErrorMessage:= aRSAData.ErrorMessage + string(ERR_error_string(err, nil)) + #10;
  19.       err := ERR_get_error;
  20.     until err = 0;
  21.     exit;
  22.   end;
  23.   rsa := EVP_PKEY_get1_RSA(FPrivateKey);
  24.   size := RSA_size(rsa);
  25.  
  26.   GetMem(data, size);
  27.   GetMem(str, size);
  28.  
  29.   b64 := BIO_new(BIO_f_base64);
  30.   mem := BIO_new_mem_buf(PAnsiChar(aRSAData.EncryptedData), Length(aRSAData.EncryptedData));
  31.   BIO_flush(mem);
  32.   mem := BIO_push(b64, mem);
  33.   BIO_read(mem, str , Length(aRSAData.EncryptedData));
  34.   BIO_free_all(mem);
  35.  
  36.   len := RSA_private_decrypt(size, PAnsiChar(str), data, rsa, RSA_PKCS1_PADDING);
  37.  
  38.   if len > 0 then
  39.   begin
  40.     SetLength(out_, len);
  41.     Move(data^, PAnsiChar(out_ )^, len);
  42.     aRSAData.ErrorResult := 0;
  43.     aRSAData.ErrorMessage := 'Base64 has been decoded and decrypted' + #10;
  44.     aRSAData.DecryptedData := out_;
  45.   end
  46.   else
  47.   begin
  48.     err := ERR_get_error;
  49.     aRSAData.ErrorResult := -1;
  50.     repeat
  51.       aRSAData.ErrorMessage := aRSAData.ErrorMessage + string(ERR_error_string(err, nil)) + #10;
  52.       err := ERR_get_error;
  53.     until err = 0;
  54.   end;
  55.   RSA_free(rsa);
  56.   FreeSSL;
  57. end;
  58.  
  59.  
  60. procedure TRSAOpenSSL.PrivateEncrypt(var aRSAData: TRSAData);
  61. var
  62.   rsa: pRSA;
  63.   str, data: AnsiString;
  64.   len, b64len: Integer;
  65.   penc64: PAnsiChar;
  66.   b64, mem: pBIO;
  67.   size: Integer;
  68.   err: Cardinal;
  69. begin
  70.   LoadSSL;
  71.   FPrivateKey := LoadPrivateKey;
  72.  
  73.   if FPrivateKey = nil then
  74.   begin
  75.     err := ERR_get_error;
  76.     repeat
  77.       aRSAData.ErrorMessage := aRSAData.ErrorMessage + string(ERR_error_string(err, nil)) + #10;
  78.       err := ERR_get_error;
  79.     until err = 0;
  80.     exit;
  81.   end;
  82.  
  83.   rsa := EVP_PKEY_get1_RSA(FPrivateKey);
  84.   EVP_PKEY_free(FPrivateKey);
  85.  
  86.   size := RSA_size(rsa);
  87.  
  88.   GetMem(FCryptedBuffer, size);
  89.   str := AnsiString(aRSAData.DecryptedData);
  90.  
  91.   len := RSA_private_encrypt(Length(str), PAnsiChar(str), FCryptedBuffer, rsa, RSA_PKCS1_PADDING);
  92.  
  93.   if len > 0 then
  94.   begin
  95.     aRSAData.ErrorResult := 0;
  96.     //create a base64 BIO
  97.     b64 := BIO_new(BIO_f_base64);
  98.     mem := BIO_push(b64, BIO_new(BIO_s_mem));
  99.     try
  100.       //encode data to base64
  101.       BIO_write(mem, FCryptedBuffer, len);
  102.       BIO_flush(mem);
  103.       b64len := BIO_get_mem_data(mem, penc64);
  104.  
  105.       //copy data to string
  106.       SetLength(data, b64len);
  107.       Move(penc64^, PAnsiChar(data)^, b64len);
  108.       aRSAData.ErrorMessage := 'String has been encrypted, then base64 encoded.' + #10;
  109.       aRSAData.EncryptedData := string(data);
  110.     finally
  111.       BIO_free_all(mem);
  112.     end;
  113.   end
  114.   else
  115.   begin
  116.     err := ERR_get_error;
  117.     aRSAData.ErrorResult := -1;
  118.     repeat
  119.       aRSAData.ErrorMessage := aRSAData.ErrorMessage + string(ERR_error_string(err, nil)) + #10;
  120.       err := ERR_get_error;
  121.     until err = 0;
  122.   end;
  123.   RSA_free(rsa);
  124. end;
  125.  

Now I'm using this code to decrypt the string but I don't want to use a file for this task
Code: Pascal  [Select][+][-]
  1. function DecryptRSAFileTo(const DecryptedFile, EncryptedFile, KeyFile: string): Boolean;
  2. var
  3.    hProcess : TProcess;
  4. begin
  5.    Result := False;
  6.    hProcess := TProcess.Create(nil);
  7.    try
  8.       //openssl rsautl -decrypt -in input.txt -out output.txt -inkey private.pem -raw
  9.       hProcess.Executable := '/usr/bin/openssl';
  10.       hprocess.Parameters.Add('rsautl'                );//'aes-256-cbc');
  11.       hprocess.Parameters.Add('-decrypt'              );//'-d -salt');
  12.       hprocess.Parameters.Add('-in'                   );//'-in secrets.txt.enc'); //input file
  13.       hprocess.Parameters.Add(EncryptedFile           );//'-in secrets.txt.enc'); //input file
  14.       hprocess.Parameters.Add('-out'                  );//'-out secrets.txt.new'); //output file
  15.       hprocess.Parameters.Add(DecryptedFile           );//'-out secrets.txt.new'); //output file
  16.       hprocess.Parameters.Add('-inkey'                );
  17.       hprocess.Parameters.Add(KeyFile                 );
  18.       hprocess.Parameters.Add('-raw'                  );
  19.       hProcess.Options := hProcess.Options + [poWaitOnExit{, poStderrToOutPut, poUsePipes}];
  20.       hProcess.Execute;
  21.  
  22.    finally
  23.       FreeAndNil(hProcess);
  24.    end;
  25.    Result := True;
  26. end;
  27.  

Thanks.

RDL

  • Jr. Member
  • **
  • Posts: 71
Re: How to decript a string using RSA Private Key ??
« Reply #1 on: February 11, 2022, 01:33:54 pm »
garlar27
At one time I solved this problem, but I had to use opensslext.pas
https://github.com/frones/ACBr/blob/master/Fontes/ACBrOpenSSL/OpenSSLExt.pas
But there are also not all the openssl functions and I had to declare them myself.
Sorry for my english, google translation!

 

TinyPortal © 2005-2018