Compatibilidad de AES256 con DCPcrypt

Continuando con las pruebas a mi implementación de AES256 (Rijndael), que empece aquí, hoy voy a probar su compatibilidad con la conocida colección de componentes DCPcrypt. Para hacerlo voy a utilizar el siguiente ejemplo que podemos encontrar el la wiki de freepascal: http://wiki.freepascal.org/DCPcrypt/es

  program ctst;
  {$mode objfpc}{$H+}
  uses
    {$IFDEF UNIX}{$IFDEF UseCThreads}
    cthreads,
    {$ENDIF}{$ENDIF}
    Sysutils, DCPrijndael;
  const
    InData: array[0..15] of byte=
      ($32,$43,$f6,$a8,$88,$5a,$30,$8d,$31,$31,$98,$a2,$e0,$37,$07,$34);
    Key1: array[0..19] of byte=
      ($2b,$7e,$15,$16,$28,$ae,$d2,$a6,$ab,$f7,$15,$88,$09,$cf,$4f,$3c,$76,$2e,$71,$60);
    Key2: array[0..31] of byte=
      ($2b,$7e,$15,$16,$28,$ae,$d2,$a6,$ab,$f7,$15,$88,$09,$cf,$4f,$3c,$76,$2e,$71,$60,
       $f3,$8b,$4d,$a5,$6a,$78,$4d,$90,$45,$19,$0c,$fe);
    OutData1: array[0..15] of byte=
      ($23,$1d,$84,$46,$39,$b3,$1b,$41,$22,$11,$cf,$e9,$37,$12,$b8,$80);
    OutData2: array[0..15] of byte=
      ($1a,$6e,$6c,$2c,$66,$2e,$7d,$a6,$50,$1f,$fb,$62,$bc,$9e,$93,$f3);
  var
    Cipher: TDCP_rijndael;
    Block: array[0..15] of byte;
  begin
  // lengths:  block = 16 bytes, key = 20 bytes
  // key     = 2b7e151628aed2a6abf7158809cf4f3c762e7160
  // input   = 3243f6a8885a308d313198a2e0370734
  // encrypt = 231d844639b31b412211cfe93712b880
  // decrypt = 3243f6a8885a308d313198a2e0370734
    Cipher:= TDCP_rijndael.Create(nil);
    Cipher.Init(Key1,Sizeof(Key1)*8,nil);
    Cipher.EncryptECB(InData,Block);
    writeln('128-bit block & 160-bit key results:');
    writeln(boolean(CompareMem(@Block,@OutData1,16)));
    Cipher.DecryptECB(Block,Block);
    writeln(boolean(CompareMem(@Block,@InData,16)));
  // lengths:  block = 16 bytes, key = 32 bytes
  // key     = 2b7e151628aed2a6abf7158809cf4f3c762e7160f38b4da56a784d9045190cfe
  // input   = 3243f6a8885a308d313198a2e0370734
  // encrypt = 1a6e6c2c662e7da6501ffb62bc9e93f3
  // decrypt = 3243f6a8885a308d313198a2e0370734
    Cipher:= TDCP_rijndael.Create(nil);
    Cipher.Init(Key2,Sizeof(Key2)*8,nil);
    Cipher.EncryptECB(InData,Block);
    writeln('128-bit block & 256-bit key results:');
    writeln(boolean(CompareMem(@Block,@OutData2,16)));
    Cipher.DecryptECB(Block,Block);
    writeln(boolean(CompareMem(@Block,@InData,16)));
  end.

En concreto nos vamos a centrar en el tamaño de clave de 256bits y utilizar los mismo datos del ejemplo:

const
  InData: array[0..15] of byte=
    ($32,$43,$f6,$a8,$88,$5a,$30,$8d,$31,$31,$98,$a2,$e0,$37,$07,$34);
  KeyData: array[0..31] of byte=
    ($2b,$7e,$15,$16,$28,$ae,$d2,$a6,$ab,$f7,$15,$88,$09,$cf,$4f,$3c,$76,$2e,$71,$60,
     $f3,$8b,$4d,$a5,$6a,$78,$4d,$90,$45,$19,$0c,$fe);
  OutData: array[0..15] of byte=
    ($1a,$6e,$6c,$2c,$66,$2e,$7d,$a6,$50,$1f,$fb,$62,$bc,$9e,$93,$f3);
 
procedure AESSwapKey(var Key: TAESKey);
var
  i: Integer;
begin
  for i:= 0 to 7 do
  begin
    Key[i]:=
      ((Key[i] and $000000FF) shl 24) or
      ((Key[i] and $0000FF00) shl 8) or
      ((Key[i] and $00FF0000) shr 8) or
      ((Key[i] and $FF000000) shr 24);
  end;
end;
 
var
  Key: TAESKey;
  ExpandedKey: TAESExpandedKey;
  State: TAESState;
begin
   Key:= TAESKey(KeyData);
  // Ajustamos el orden de los bytes dentro del array 
   AESSwapKey(Key);
   AESExpandKey(ExpandedKey,Key);
   State:= TAESState(InData);
   AESEncrypt(State,ExpandedKey);
   Writeln(boolean(CompareMem(@State,@OutData,16)));
end; 

Si todo es correcto el código anterior debe mostrar por pantalla "TRUE", que es efectivamente lo que muestra. El único detalle a tener en cuenta es que hemos corregido el orden de los bytes en la clave, usando la función AESSwapKey, para que se ajuste al mismo orden que utilizamos nosotros.

Añadir nuevo comentario