2012-06-12 28 views
7

Tengo el siguiente código C# que genera claves:Diferencia entre cifrado .NET y PHP

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 realizar la misma cosa en PHP:

function get_encrypted_key($key){ 
    $salt = "abcdefgh"; 
    return bin2hex(mcrypt_encrypt(MCRYPT_DES, $salt, $key, MCRYPT_MODE_CBC, $salt)); 
} 

Sin embargo, no es una pequeña discrepancia en los resultados, ya que los últimos 16 caracteres son siempre diferentes:

With key "Benjamin Franklin": 
C# : 0B3C6E5DF5D747FB3C50DE952FECE3999768F35B890BC391 
PHP: 0B3C6E5DF5D747FB3C50DE952FECE3993A881F9AF348C64D 

With key "President Franklin D Roosevelt": 
C# : C119B50A5A7F8C905A86A43F5694B4D7DD1E8D0577F1CEB32A86FABCEA5711E1 
PHP: C119B50A5A7F8C905A86A43F5694B4D7DD1E8D0577F1CEB37ACBE60BB1D21F3F 

también he intentado llevar a cabo el relleno t transformar a 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 tiene alguna idea de lo que está pasando, ¡me encantaría saberlo! :)

Gracias

+3

Tal vez un resultado de diferentes esquemas de relleno? – mensi

+2

Si con el fragmento de relleno "clásico", te refieres al que se menciona en la parte superior de las notas en 'mcrypt_encrypt', eso me da los resultados de' C# 'de PHP. Tenga en cuenta que el fragmento usa ECB, no CBC, por lo que debe ajustarlo. –

+0

Gracias por sus comentarios chicos. He detallado el código que utilicé para el relleno. Buscaré en el enlace de John. – karlipoppins

Respuesta

4

Usted ha mencionado tratando un fragmento de "clásico" de relleno. La siguiente adaptación rápida del fragmento publicado en el mcrypt_encrypt documentation da los mismos resultados que obtenía de C#.

PKCS # 7 (el esquema de relleno predeterminado utilizado por C# SymmetricAlgorithm) almohadillas con bytes donde el valor de cada byte 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 la prueba:

php > echo get_encrypted_key('Benjamin Franklin'); 
0b3c6e5df5d747fb3c50de952fece3999768f35b890bc391 
php > echo get_encrypted_key('President Franklin D Roosevelt'); 
c119b50a5a7f8c905a86a43f5694b4d7dd1e8d0577f1ceb32a86fabcea5711e1 
+0

Muchas gracias John, eso es perfecto – karlipoppins

Cuestiones relacionadas