2010-03-18 11 views
5

Quando ho cifrare con C# che ricevo arTdPqWOg6VppOqUD6mGITjb24+x5vJjfAufNQ4DN7rVEtpDmhFnMeJGg4n5y1BNTripleDES crittografia non cedendo stessi risultati in PHP e 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); 
} 

Quando ho cifrare con PHP ottengo: 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); 
    ?> 

io non ne so abbastanza sulla crittografia per capire perché. Qualche idea? Grazie.

+0

I risultati di ogni consistente? Almeno per gli hash, credo che generino un sale casuale. – Jonah

risposta

6

Peter ha ragione. PHP solo pad con zeri, mentre stai usando PKCS # 7 nel codice C#. Ecco un po 'di codice che dovrebbe farlo bene:

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); 

In alternativa, si dovrebbe essere in grado di mettere questo nel vostro codice C#:

tdes.Padding = PaddingMode.Zeros; 

e hanno anche farlo funzionare (anche se un po' meno sicuro).

2

Non conosco PHP e non ho analizzato il codice C# con attenzione, ma poiché la maggior parte della stringa crittografata è la stessa forse il riempimento dei dati è la differenza? Forse PHP usa un'altra modalità rispetto allo PaddingMode.PKCS7 utilizzato nel codice C#? (Questo sarebbe stato un commento se potessi commentare ...)

0

Come nota a margine: se si utilizza l'ECB, non è necessario un IV. In realtà, l'utilizzo della BCE è per la maggior parte del tempo un rischio per la sicurezza, quindi è davvero necessario utilizzare qualcos'altro, ad es. CBC, che usa una flebo. L'IV è un valore casuale non segreto con le stesse dimensioni della dimensione del blocco di cifratura (8 byte per 3DES). È necessario creare una nuova IV per ciascun messaggio e la parte decrittante deve conoscere la IV utilizzata dalla parte crittografica. In pratica, l'IV viene inviato insieme al messaggio crittografato.

Problemi correlati