2010-02-11 7 views
6

que descifrar los datos usando PHP con este código:no puede descifrar los datos con C# que haya cifrado con PHP (Rijdael-128)

$content="1234"; 
$cp = mcrypt_module_open('rijndael-128', '', 'cbc', ''); 
$iv = mcrypt_create_iv(16, MCRYPT_RAND); 
$key = pack("H*",md5('a')); 
mcrypt_generic_init($cp, $key, $iv); 
$encrypted = mcrypt_generic($cp, $content); 
echo base64_encode($key)."\n"; 
echo base64_encode($iv)."\n"; 
echo base64_encode($encrypted)."\n"; 
mcrypt_generic_deinit($cp); 
mcrypt_module_close($cp); 

$ IV y $ cifrada entonces se guarda en un archivo y leer en la muestra C# aplicación:

var iv=...; 
var encrypted=...; 
var md5 = new MD5CryptoServiceProvider(); 
var key = md5.ComputeHash(Encoding.Default.GetBytes("a")); 
md5.Clear(); 

Console.WriteLine(Convert.ToBase64String(key)); 
Console.WriteLine(Convert.ToBase64String(iv)); 
Console.WriteLine(Convert.ToBase64String(encrypted)); 

la salida aquí es exactamente la misma que la salida de PHP, por lo que se puede asegurar que no haya errores de codificación entre medio.

var rd = new RijndaelManaged { 
    Key = key, 
    IV = iv, 
    Mode = CipherMode.CBC, 
    KeySize = 128, 
    Padding = PaddingMode.Zeros 
}; 

var buffer = new byte[encrypted.Length]; 
using(var ms = new MemoryStream(buffer)) { 
    using(var cs = new CryptoStream(ms, rd.CreateDecryptor(), CryptoStreamMode.Write)) { 
    cs.Write(encrypted, 0, encrypted.Length); 
    ms.Read(buffer, 0, buffer.Length); 
    Console.WriteLine(Encoding.Default.GetString(buffer)); 
    } 
} 
rd.Clear(); 

El resultado del descifrado varía en cada inicio del programa, incluso con exactamente los mismos datos de entrada:

Primera carrera:
DMF1ucDxtqgxw5niaXcmYQ == < -Tecla
GoCeRkrL/EMKNH/BYeLsqQ == < -IV
UBE3DkgbJgj1K/TISugLxA == < -Encrypted
OlOB99yiCYRDoLx + 0xxZxQ == < - "descifrado"

segunda pasada:
DMF1ucDxtqgxw5niaXcmYQ == < -Tecla
GoCeRkrL/EMKNH/BYeLsqQ == < -IV
UBE3DkgbJgj1K/TISugLxA == < -Encrypted
w5fcY5Fbb9KRgoHfhqAztA == < - "descifrado"

Clave , IV, los datos cifrados son idénticos, pero la fecha desencriptada varía y siempre es incorrecta. el búfer debe contener "1234" o "1234" más 12 ceros al final.

no veo por qué los resultados varían y lo que no funciona, pero he estado mirando esta pieza de código maldito durante varias horas ahora, y probablemente de menos el error obvio ...

La inversión de la CryptoStream como este crea resultados idénticamente incorrectos:

using(var ms = new MemoryStream(encrypted)) { 
    using(var cs = new CryptoStream(ms, rd.CreateDecryptor(), CryptoStreamMode.Read)) { 
    cs.Read(buffer, 0, buffer.Length); 
    Console.WriteLine(Convert.ToBase64String(buffer)); 
    } 
} 

¿Ayuda? Gracias! Alexander

Respuesta

5

Bueno, la modificación de una vieja muestra de mis pecados del pasado terminé con esto:

static string Decrypt() {    
    byte[] keyBytes = Convert.FromBase64String("DMF1ucDxtqgxw5niaXcmYQ=="); 
    byte[] iv = Convert.FromBase64String("GoCeRkrL/EMKNH/BYeLsqQ=="); 
    byte[] cipherTextBytes = Convert.FromBase64String("UBE3DkgbJgj1K/TISugLxA=="); 

    var symmetricKey = new RijndaelManaged { Mode = CipherMode.CBC, IV = iv, KeySize = 128, Key = keyBytes, Padding = PaddingMode.Zeros}; 

    using (var decryptor = symmetricKey.CreateDecryptor()) 
    using (var ms = new MemoryStream(cipherTextBytes)) 
    using (var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read)) { 
    var plainTextBytes = new byte[cipherTextBytes.Length]; 
    int decryptedByteCount = cs.Read(plainTextBytes, 0, plainTextBytes.Length); 
    return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount); 
    } 
} 

que dio "1234" con arrastrarse caracteres \ 0 .. ¿Acaba de olvidar para convertir el byte [] a una cadena de nuevo? ¿Qué otra diferencia me estoy perdiendo?

+0

La solución es muy simple, pero en su mayoría molesta ... Tiene que establecer la propiedad "KeySize" * antes de * establecer la propiedad "Key". He convertido mi código paso a paso para que coincida con su código, y tan pronto como cambié los dos setters, funcionó. En caso de que alguien de Microsoft esté escuchando, puede incluir esa información en MSDN. Sé que es obvio una vez que lo sabes, pero ... Benjamin, Danke! –

Cuestiones relacionadas