Diferencia entre el cifrado .NET y PHP
Frecuentes
Visto 1,160 veces
7
Tengo el siguiente código C# que genera claves:
public static byte[] Encrypt(byte[] plainData, string salt)
{
DESCryptoServiceProvider DES = new DESCryptoServiceProvider();
DES.Key = ASCIIEncoding.ASCII.GetBytes(salt);
DES.IV = ASCIIEncoding.ASCII.GetBytes(salt);
ICryptoTransform desencrypt = DES.CreateEncryptor();
byte[] encryptedData = desencrypt.TransformFinalBlock(plainData, 0, plainData.Length);
return encryptedData;
}
private string GetEncryptedKey(string key)
{
return BitConverter.ToString(KeyGeneratorForm.Encrypt(ASCIIEncoding.ASCII.GetBytes(key), "abcdefgh")).Replace("-", "");
}
Estoy tratando de hacer lo mismo en PHP:
function get_encrypted_key($key){
$salt = "abcdefgh";
return bin2hex(mcrypt_encrypt(MCRYPT_DES, $salt, $key, MCRYPT_MODE_CBC, $salt));
}
Sin embargo, existe una pequeña discrepancia en los resultados, ya que los últimos 16 caracteres siempre son diferentes:
With key "Benjamin Franklin":
C# : 0B3C6E5DF5D747FB3C50DE952FECE3999768F35B890BC391
PHP: 0B3C6E5DF5D747FB3C50DE952FECE3993A881F9AF348C64D
With key "President Franklin D Roosevelt":
C# : C119B50A5A7F8C905A86A43F5694B4D7DD1E8D0577F1CEB32A86FABCEA5711E1
PHP: C119B50A5A7F8C905A86A43F5694B4D7DD1E8D0577F1CEB37ACBE60BB1D21F3F
También intenté realizar la transformación de relleno en mi clave usando el siguiente código:
function get_encrypted_key($key){
$salt = "abcdefgh";
$extra = 8 - (strlen($key) % 8);
if($extra > 0) {
for($i = 0; $i < $extra; $i++) {
$key.= "\0";
}
}
return bin2hex(mcrypt_encrypt(MCRYPT_DES, $salt, $key, MCRYPT_MODE_CBC, $salt));
}
Pero termino con los mismos resultados que sin relleno.
Si tienes alguna idea de lo que está pasando, ¡me encantaría saberlo! :)
Muchas Gracias
1 Respuestas
4
Mencionaste probar un fragmento de relleno "clásico". La siguiente adaptación rápida del fragmento publicado en el mcrypt_encrypt
documentación da los mismos resultados que estaba obteniendo de C#.
PKCS #7 (el esquema de relleno predeterminado utilizado por C# SymmetricAlgorithm
) rellenos con bytes donde el valor de cada byte de relleno es el mismo que el número de bytes de relleno, no con cero bytes.
function get_encrypted_key($key)
{
$salt = 'abcdefgh';
$block = mcrypt_get_block_size('des', 'cbc');
$pad = $block - (strlen($key) % $block);
$key .= str_repeat(chr($pad), $pad);
return bin2hex(mcrypt_encrypt(MCRYPT_DES, $salt, $key, MCRYPT_MODE_CBC, $salt));
}
Salida de prueba:
php > echo get_encrypted_key('Benjamin Franklin');
0b3c6e5df5d747fb3c50de952fece3999768f35b890bc391
php > echo get_encrypted_key('President Franklin D Roosevelt');
c119b50a5a7f8c905a86a43f5694b4d7dd1e8d0577f1ceb32a86fabcea5711e1
Respondido el 12 de junio de 12 a las 22:06
Muchas gracias John, eso es perfecto. koni
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas php .net encryption des or haz tu propia pregunta.
¿Quizás como resultado de diferentes esquemas de relleno? - mensi
Si por fragmento de relleno "clásico" se refiere al que se menciona justo en la parte superior de las notas en
mcrypt_encrypt
, que me da tuC#
resultados de PHP. Tenga en cuenta que el fragmento usa ECB, no CBC, por lo que debe modificarlo. - John FlatnessGracias por vuestros comentarios chicos. He detallado el código que usé para el relleno. Buscaré el enlace de John. - koni
¿Qué tal tirarlo todo junto y reemplazarlo con algo que no apesta? - CodesInChaos
@CodeInChaos ¿Qué agregaría a la respuesta correcta dada? - koni