Peacelyk
Peacelyk

Reputation: 1146

Rijndael encryption. First characters are weird

Code i'm using (XE):

// Encrypt a string and return the Base64 encoded result
function Encrypt(DataToEncrypt: ansistring):ansistring;
const Key: Ansistring = 'keykey';
  KeySize = 32; // 32 bytes = 256 bits
  BlockSize = 16; // 16 bytes = 128 bits
var
  Cipher : TDCP_rijndael;
  Data: ansistring;
  IV: array[0..15] of byte;      // the initialization vector
  i:Integer;
begin
  // Pad Key, IV and Data with zeros as appropriate
  FillChar(IV,Sizeof(IV),0);            // make the IV all zeros

  Data := PadWithZeros(DataToEncrypt,BlockSize);

  for i := 0 to (Length(IV) - 1) do   //just random values for the IV
    IV[i] := Random(256);

  Cipher := TDCP_rijndael.Create(nil);

  if Length(Key) <= 16 then
    Cipher.Init(Key[1],128,@IV[1])
  else if Length(Key) <= 24 then
    Cipher.Init(Key[1],192,@IV[1])
  else
    Cipher.Init(Key[1],256,@IV[1]);
  // Encrypt the data
  Cipher.EncryptCBC(Data[1],Data[1],Length(Data));
  // Free the cipher and clear sensitive information
  Cipher.Free;

  SetString(InitializationVector,PAnsiChar(@IV[1]),Length(IV));  //Save IV
  InitializationVector := Base64EncodeStr(InitializationVector);

  //Base64 encoded result
  Result := Base64EncodeStr(Data);
end;

function Decrypt(IV,Cryptogram:ansistring):ansistring;
const Key: Ansistring = 'keykey';
  KeySize = 32; // 32 bytes = 256 bits
  BlockSize = 16; // 16 bytes = 128 bits
var
  Cipher : TDCP_rijndael;
begin
  if IV='' then
    IV := InitializationVector;

  Cryptogram := Base64DecodeStr(cryptogram);
  // Create the cipher and initialise according to the key length
  cipher := tdcp_rijndael.Create(nil);
  if Length(Key) <= 16 then
    Cipher.Init(Key[1],128,@IV[1])
  else if Length(Key) <= 24 then
    Cipher.Init(Key[1],192,@IV[1])
  else
    Cipher.Init(Key[1],256,@IV[1]);
  // Decrypt the data
  Cipher.DecryptCBC(cryptogram[1],cryptogram[1],Length(cryptogram));
  // Free the cipher and clear sensitive information
  Cipher.Free;
  // Display the result
  Result := cryptogram;
end;

It works pretty well, except when i try to decrypt the string, i get:

$C#$C'Ç'#$B'ÛW'#$1F'Ø‹™Ç'#$8D'Ž'#$8D'!‘mydata

so first few letters get very weird characters. rest of it is decrypted just fine! Found similar problem here, but no solution. Thanks in advance!

Upvotes: 0

Views: 1075

Answers (1)

Paul-Jan
Paul-Jan

Reputation: 17278

The first thing that stands out to me is that you are reading/writing past the end of IV. You declare it as [0..15] but access everything from element 1(!) onwards, both in Cipher.Init and SetString.

Upvotes: 5

Related Questions