Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   error en desencriptación aes (https://www.clubdelphi.com/foros/showthread.php?t=96764)

Galahad 27-06-2024 19:03:33

error en desencriptación aes
 
Hola, buenas tardes
Estoy intentando utilizar la libreria DCcrypt2 para desencriptar una cadena de texto que consigo a partir de un servicio REST.
utilizando el código inferior se produce el error 'Range check error' en la línea que muestro a continuación

"DCP_rijndael.Init(apisecret[1], 128, @iv[1]);")

¿ alguien sabe porque puede ser o si se puede hacer de otra manera con estos componentes ?
Por otro lado, trabajamos con Delphi 12.1 , ¿ no tiene algo delphi de manera nativa para trabajar con este tipo de encriptado (aes/cbc) ?.
Lo he estado buscando , pero no he encontrado nada.


Código Delphi [-]
function Decrypt( Astr,apikey,apisecret:String ):string;
var d,s,iv:string;
    DCP_rijndael: TDCP_rijndael;
begin
  d:= Base64Decodestr(astr);
  DCP_rijndael := TDCP_rijndael.Create(self);
  try
    DCP_rijndael.Algorithm := 'AES/CBC/PKCS5PADDING';
    DCP_rijndael.CipherMode := cmCBC;
    DCP_rijndael.Init(apisecret[1], 128, @iv[1]);
    DCP_rijndael.SetIV(apikey);
    DCP_rijndael.DecryptCBC(d,s,Length(d));
  finally
    DCP_rijndael.free;
  end;

end;

Casimiro Notevi 27-06-2024 19:36:22

"Range check error" suele indicar que estás accediendo a una posición de memoria que no es válida, pueden ser varios motivos:
Asegúrate de que las cadenas tienen la longitud correcta y gestiona bien el IV (vector de inicialización), el CBC, el IV debe tener la longitud correcta.
Un ejemplo de código que tenía guardado por aqui de alguna vez que me ha hecho falta:
Código Delphi [-]
uses
  DCPcrypt2, DCPblockciphers, DCPaes, SysUtils, Classes;

function Decrypt(Astr, apikey, apisecret: string): string;
var
  d, s: string;
  iv: array[0..15] of Byte;
  DCP_rijndael: TDCP_rijndael;
  DecodedStream, DecryptedStream: TMemoryStream;
begin
  Result := '';
  if Length(apisecret) <> 16 then
    raise Exception.Create('API secret must be 16 characters long.');

  // Decode the base64-encoded string
  d := Base64Decodestr(Astr);

  // Create and initialize the Rijndael (AES) cipher
  DCP_rijndael := TDCP_rijndael.Create(nil);
  try
    // Set up the initialization vector (IV)
    FillChar(iv, SizeOf(iv), 0); // Assuming iv is just zeros
    Move(apikey[1], iv, Min(Length(apikey), SizeOf(iv)));

    // Initialize the cipher with the key and IV
    DCP_rijndael.Init(apisecret[1], 128, @iv);

    // Decrypt the data
    DecodedStream := TMemoryStream.Create;
    try
      DecodedStream.WriteBuffer(Pointer(d)^, Length(d));
      DecodedStream.Position := 0;

      DecryptedStream := TMemoryStream.Create;
      try
        DCP_rijndael.DecryptStream(DecodedStream, DecryptedStream, DecodedStream.Size);
        SetLength(s, DecryptedStream.Size);
        DecryptedStream.Position := 0;
        DecryptedStream.ReadBuffer(Pointer(s)^, DecryptedStream.Size);
        Result := s;
      finally
        DecryptedStream.Free;
      end;
    finally
      DecodedStream.Free;
    end;
  finally
    DCP_rijndael.Free;
  end;
end;

Galahad 28-06-2024 18:38:06

Muchas gracias Casimiro
Se que la longitud tiene que ser de 16 caracteres
voy a seguir peleandome porque no lo consigo, ahora me da un access violation
este es el código de la función con la que estoy trabajando (en base a la que habias puesto)

Código Delphi [-]
function Decrypt(Astr, apikey, apisecret: string): string;
var
  d, s: string;
  iv: array[0..15] of Byte;
  DCP_rijndael: TDCP_rijndael;
  DecodedStream, DecryptedStream: TMemoryStream;
  Len:Integer;
  Padding : char;
begin
  Result := '';
  //if Length(apisecret) <> 16 then
  //  raise Exception.Create('API secret must be 16 characters long.');

  // Decode the base64-encoded string
  d := Base64Decodestr(Astr);
  Len := 16;
  Padding := '$';
  apikey := Format('%-*s', [Len, apikey]).Replace(' ', Padding);
  if Length(apikey) > Len then
    apikey := Copy(apikey, 1, Len);
  apisecret := Format('%-*s', [Len, apisecret]).Replace(' ', Padding);
  if Length(apisecret) > Len then
    apisecret := Copy(apisecret, 1, Len);

  // Create and initialize the Rijndael (AES) cipher
  DCP_rijndael := TDCP_rijndael.Create(nil);
  try
    DCP_rijndael.Algorithm := 'AES/CBC/PKCS5PADDING';
    DCP_rijndael.CipherMode := cmCBC;

    // Set up the initialization vector (IV)
    FillChar(iv, SizeOf(iv), 0); // Assuming iv is just zeros
    Move(apikey[1], iv, Min(Length(apikey), SizeOf(iv)));

    // Initialize the cipher with the key and IV
    DCP_rijndael.Init(apisecret[1], 128, @iv);
    // Decrypt the data
    DecodedStream := TMemoryStream.Create;
    try
      DecodedStream.WriteBuffer(Pointer(d)^, Length(d));
      DecodedStream.Position := 0;

      DecryptedStream := TMemoryStream.Create;
      try
        DCP_rijndael.DecryptStream(DecodedStream, DecryptedStream, DecodedStream.Size);
        SetLength(s, DecryptedStream.Size);
        DecryptedStream.Position := 0;
        DecryptedStream.ReadBuffer(Pointer(s)^, DecryptedStream.Size);
        Result := s;
      finally
        DecryptedStream.Free;
      end;
    finally
      DecodedStream.Free;
    end;
  finally
    DCP_rijndael.Free;
  end;
end;

Cita:

Empezado por Casimiro Notevi (Mensaje 556402)
"Range check error" suele indicar que estás accediendo a una posición de memoria que no es válida, pueden ser varios motivos:
Asegúrate de que las cadenas tienen la longitud correcta y gestiona bien el IV (vector de inicialización), el CBC, el IV debe tener la longitud correcta.
Un ejemplo de código que tenía guardado por aqui de alguna vez que me ha hecho falta:
Código Delphi [-]
uses
  DCPcrypt2, DCPblockciphers, DCPaes, SysUtils, Classes;

function Decrypt(Astr, apikey, apisecret: string): string;
var
  d, s: string;
  iv: array[0..15] of Byte;
  DCP_rijndael: TDCP_rijndael;
  DecodedStream, DecryptedStream: TMemoryStream;
begin
  Result := '';
  if Length(apisecret) <> 16 then
    raise Exception.Create('API secret must be 16 characters long.');

  // Decode the base64-encoded string
  d := Base64Decodestr(Astr);

  // Create and initialize the Rijndael (AES) cipher
  DCP_rijndael := TDCP_rijndael.Create(nil);
  try
    // Set up the initialization vector (IV)
    FillChar(iv, SizeOf(iv), 0); // Assuming iv is just zeros
    Move(apikey[1], iv, Min(Length(apikey), SizeOf(iv)));

    // Initialize the cipher with the key and IV
    DCP_rijndael.Init(apisecret[1], 128, @iv);

    // Decrypt the data
    DecodedStream := TMemoryStream.Create;
    try
      DecodedStream.WriteBuffer(Pointer(d)^, Length(d));
      DecodedStream.Position := 0;

      DecryptedStream := TMemoryStream.Create;
      try
        DCP_rijndael.DecryptStream(DecodedStream, DecryptedStream, DecodedStream.Size);
        SetLength(s, DecryptedStream.Size);
        DecryptedStream.Position := 0;
        DecryptedStream.ReadBuffer(Pointer(s)^, DecryptedStream.Size);
        Result := s;
      finally
        DecryptedStream.Free;
      end;
    finally
      DecodedStream.Free;
    end;
  finally
    DCP_rijndael.Free;
  end;
end;



La franja horaria es GMT +2. Ahora son las 23:20:02.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi