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