2010-03-18 17 views
5

Cuando Cifrar con C# que recibo arTdPqWOg6VppOqUD6mGITjb24+x5vJjfAufNQ4DN7rVEtpDmhFnMeJGg4n5y1BNcifrado TripleDES no ceder mismos resultados en PHP y C#

static void Main(string[] args) 
{ 
    Encoding byteEncoder = Encoding.Default; 

    String key = "ShHhd8a08JhJiho98ayslcjh"; 
    String message = "Let us meet at 9 o'clock at the secret place."; 

    String encryption = Encrypt(message, key, false); 
    String decryption = Decrypt(encryption , key, false); 

    Console.WriteLine("Message: {0}", message); 
    Console.WriteLine("Encryption: {0}", encryption); 
    Console.WriteLine("Decryption: {0}", decryption); 
} 

public static string Encrypt(string toEncrypt, string key, bool useHashing) 
{ 
    byte[] keyArray; 
    byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt); 

    if (useHashing) 
    { 
     MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider(); 
     keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key)); 
    } 
    else 
     keyArray = UTF8Encoding.UTF8.GetBytes(key); 

    TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider(); 
    tdes.Key = keyArray; 
    tdes.Mode = CipherMode.ECB; 
    tdes.Padding = PaddingMode.PKCS7; 

    ICryptoTransform cTransform = tdes.CreateEncryptor(); 
    byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length); 

    return Convert.ToBase64String(resultArray, 0, resultArray.Length); 
} 

public static string Decrypt(string toDecrypt, string key, bool useHashing) 
{ 
    byte[] keyArray; 
    byte[] toEncryptArray = Convert.FromBase64String(toDecrypt); 

    if (useHashing) 
    { 
     MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider(); 
     keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key)); 
    } 
    else 
     keyArray = UTF8Encoding.UTF8.GetBytes(key); 

    TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider(); 
    tdes.Key = keyArray; 
    tdes.Mode = CipherMode.ECB; 
    tdes.Padding = PaddingMode.PKCS7; 

    ICryptoTransform cTransform = tdes.CreateDecryptor(); 
    byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length); 

    return UTF8Encoding.UTF8.GetString(resultArray); 
} 

Cuando Cifrar con PHP me sale: arTdPqWOg6VppOqUD6mGITjb24+x5vJjfAufNQ4DN7rVEtpDmhFnMVM+W/WFlksR

<?php 
     $key = "ShHhd8a08JhJiho98ayslcjh"; 
     $input = "Let us meet at 9 o'clock at the secret place."; 

     $td = mcrypt_module_open('tripledes', '', 'ecb', ''); 
     $iv = mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_RAND); 
     mcrypt_generic_init($td, $key, $iv); 
     $encrypted_data = mcrypt_generic($td, $input); 
     mcrypt_generic_deinit($td); 
     mcrypt_module_close($td); 

     echo base64_encode($encrypted_data); 
    ?> 

No sé lo suficiente acerca de la criptografía para descubrir por qué. ¿Algunas ideas? Gracias.

+0

¿Los resultados de cada uno son consistentes? Al menos para los hashes, creo que generan una sal aleatoria. – Jonah

Respuesta

6

Peter tiene razón. PHP solo hace clic con ceros, mientras usa PKCS # 7 en el código C#. Aquí hay un código que debe hacerlo bien:

function pkcs7_pad($text, $blocksize) 
{ 
    $pad = $blocksize - (strlen($text) % $blocksize); 
    return $text . str_repeat(chr($pad), $pad); 
} 

$input = pkcs7_pad("Let us meet at 9 o'clock at the secret place.", 16); 

Alternativamente, usted debe ser capaz de poner esto en su código C#:

tdes.Padding = PaddingMode.Zeros; 

y también tienen que trabajar (aunque un poco menos segura).

2

No sé PHP, y tampoco he analizado su código C# cuidadosamente, pero como la mayoría de las cadenas cifradas son las mismas, ¿tal vez el relleno de los datos es la diferencia? Tal vez PHP utiliza otro modo que el PaddingMode.PKCS7 utilizado en el código C#? (Esto hubiera sido un comentario si pudiera comentar ...)

0

Como nota al margen: si está utilizando BCE, entonces no necesita un IV. En realidad, usar BCE es la mayor parte del tiempo un riesgo de seguridad, por lo que realmente necesita usar algo más, p. CBC, que usa un IV. El IV es un valor aleatorio, no secreto, con el mismo tamaño que el tamaño del bloque de cifrado (8 bytes para 3DES). Se debe crear un nuevo IV para cada mensaje, y el desencriptador debe conocer el IV que utilizó el encriptador. En la práctica, el IV se envía junto con el mensaje cifrado.