Actualización 2: funciona
Gracias a Tom Leek por su respuesta.
El modo CFB
de mycrypt
para Rijndael
usa un bucle de retroalimentación de 8 bits y no un bucle de retroalimentación de la longitud de la clave / iv.
Tienes que obligarlo a usar la longitud completa con el parámetro ncfb
. Confusamente, esta no es una constante documentada en la biblioteca de PHP Mcrypt: enlace
Las líneas apropiadas en el PHP ahora se ven así:
$Crypt = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $Key, $Text, 'ncfb', $IV);
$Decrypt = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $Key, $Crypt, 'ncfb', $IV);
Actualizado - ver abajo
Estoy tratando de obtener un sitio de Erlang para intercambiar información a través del cifrado aes_cfb_128
con un sitio PHP. Estoy escribiendo una implementación de prueba que demostrará que el PHP descifra lo que el Erlang encripta y viceversa, pero tengo problemas.
Aquí está la fuente de PHP (disculpas, es un poco de mala calidad, mi PHP no es bueno, soy un programador de Erlang):
<?php
function dump($String, $Bin) {
echo $String . " is " . ord($Bin[0]) . " " . ord($Bin[1]) . " " . ord($Bin[2]) . " " . ord($Bin[3]) . " " . ord($Bin[4]) . " " . ord($Bin[5]) . " " . ord($Bin[6]) . " " . ord($Bin[7]) . " " . ord($Bin[8]) . " " . ord($Bin[9]) . " " . ord($Bin[10]) . " " . ord($Bin[11]) . " " . ord($Bin[12]) . " " . ord($Bin[13]) . " " . ord($Bin[14]) . " " . ord($Bin[15]) . " " . ord($Bin[16]) . " " . ord($Bin[17]) . " " . ord($Bin[18]) . " " . ord($Bin[19]) . " " . ord($Bin[20]) . " " . ord($Bin[21]) . " " . ord($Bin[22]) . " " . ord($Bin[23]) . " " . ord($Bin[24]) . " " . ord($Bin[25]) . " " . ord($Bin[26]) . " " . ord($Bin[27]) . " " . ord($Bin[28]) . " " . ord($Bin[29]) . " " . ord($Bin[30]) . " " . ord($Bin[31]) ."\n";
}
$Key = "abcdefghabcdefgh";
$IV = "12345678abcdefgh";
$Text = "12345678123456781234567812345678";
$KeySize = strlen($Key) * 8;
$IVSize = strlen($IV) * 8;
$TextSize = strlen($Text) * 8;
$IVSize = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_NOFB);
echo "IVSze is " . $IVSize . " bytes or " . $IVSize * 8 . " bits\n";
$BlockSize = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_NOFB);
echo "BlockSize is " . $BlockSize . " bytes or " . $IVSize * 8 . " bits\n";
$Crypt = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $Key, $Text, MCRYPT_MODE_NOFB, $IV);
$Decrypt = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $Key, $Crypt, MCRYPT_MODE_NOFB, $IV);
echo "Key is " . $Key . " with size " . $KeySize . "\n";
echo "IV is " . $IV . " with size " . $IVSize . "\n";
echo "Text is " . $Text . " with size " . $TextSize . "\n";
echo "Crypt is " . $Crypt . "\n";
dump("Crypt", $Crypt);
echo "Decrypt is " . $Decrypt . "\n";
dump("Decrypt", $Decrypt);
?>
Aquí está la fuente correspondiente de Erlang:
-module(test_crypto).
-export([
test/0
]).
test() ->
Key = <<"abcdefghabcdefgh">>,
IV = <<"12345678abcdefgh">>,
Text = <<"12345678123456781234567812345678">> ,
KeySize = bit_size(Key),
IVSize = bit_size(IV),
TextSize = bit_size(Text),
io:format("Key is ~p with size ~p~n", [Key, KeySize]),
io:format("IV is ~p with size ~p~n", [IV, IVSize]),
io:format("Text is ~p with size ~p~n", [Text, TextSize]),
Crypt = crypto:aes_cfb_128_encrypt(Key, IV, Text),
io:format("Crypt is ~p~n", [Crypt]),
B64 = base64:encode(Crypt),
io:format("Crypt B64 is ~p~n", [B64]),
Decrypt = crypto:aes_cfb_128_decrypt(Key, IV, Crypt),
io:format("Decrypt is ~p~n", [Decrypt]),
ok.
Aquí está la salida de PHP:
gordon@hypernumbers:~/crypto$ php test_crypto.php
IVSze is 16 bytes or 128 bits
BlockSize is 16 bytes or 128 bits
Key is abcdefghabcdefgh with size 128
IV is 12345678abcdefgh with size 16
Text is 12345678123456781234567812345678 with size 256
Crypt is ��^DЭZ�!�)�y�9�������ht���'!
Crypt is 139 182 94 68 208 173 127 90 14 236 33 230 41 29 210 121 153 57 173 191 237 169 242 222 217 104 116 144 240 175 39 33
Decrypt is 12345678123456781234567812345678
Decrypt is 49 50 51 52 53 54 55 56 49 50 51 52 53 54 55 56 49 50 51 52 53 54 55 56 49 50 51 52 53 54 55 56
Aquí está la salida de Erlang:
7> test_crypto:test().
Key is <<"abcdefghabcdefgh">> with size 128
IV is <<"12345678abcdefgh">> with size 128
Text is <<"12345678123456781234567812345678">> with size 256
Crypt is <<139,182,94,68,208,173,127,90,14,236,33,230,41,29,210,121,147,172,
114,74,61,11,162,5,112,104,102,63,24,78,34,179>>
Crypt B64 is <<"i7ZeRNCtf1oO7CHmKR3SeZOscko9C6IFcGhmPxhOIrM=">>
Decrypt is <<"12345678123456781234567812345678">>
ok
Como puede ver, ambos bloques de código se completan correctamente, pero no funcionarán juntos porque no crean el texto cifrado idéntico.
Los primeros 16 bytes del cipertexto son iguales, pero el segundo bloque de 16 bytes es diferente.
Sé que este algoritmo usa el primer bloque de salida en el cifrado del segundo, por lo que sospecho que hay algunos problemas entre el modo en que el módulo Erlang crypto
lo está haciendo y el código PHP mcrypt
.
ACTUALIZAR
Intenté usar el modo CFB en mycrypt pero creo que hay un tamaño de bloque de comentarios diferente o algo así, y solo el primer carácter del cipertexto fue el mismo. El modo NOFB parece estar relacionado de alguna manera y es lo mejor que he conseguido hasta ahora ...
Si ejecuto el modo PHP con CFB obtengo esta salida:
~/crypto$ php test_crypto.php
IVSze is 16 bytes or 128 bits
BlockSize is 16 bytes or 128 bits
Key is abcdefghabcdefgh with size 128
IV is 12345678abcdefgh with size 16
Text is 12345678123456781234567812345678 with size 256
Crypt is ��*�b�ls�M����
��ҮF��Y�=O
Crypt is 139 0 188 42 175 98 18 177 108 27 115 189 77 144 127 176 171 193 11 32 245 139 210 174 70 151 230 89 169 22 61 79
Decrypt is 12345678123456781234567812345678
Decrypt is 49 50 51 52 53 54 55 56 49 50 51 52 53 54 55 56 49 50 51 52 53 54 55 56 49 50 51 52 53 54 55 56
Intenté obtener ayuda en StackOverflow enlace pero era sobre todo yo hablando conmigo mismo :(