2010-03-18 3 views
5

Wenn ich mit C# verschlüsseln ich arTdPqWOg6VppOqUD6mGITjb24+x5vJjfAufNQ4DN7rVEtpDmhFnMeJGg4n5y1BNTripleDES Verschlüsselung wodurch man nicht gleiche Ergebnisse in PHP und 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); 
} 

, wenn ich mit PHP verschlüsseln erhalte ich: 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); 
    ?> 

Ich weiß nicht genug über Kryptographie, um herauszufinden, warum. Irgendwelche Ideen? Vielen Dank.

+0

Sind die Ergebnisse von jedem konsistent? Zumindest für Hashes glaube ich, dass sie ein zufälliges Salz erzeugen. – Jonah

Antwort

6

Peter hat Recht. PHP füllt nur mit Nullen, während Sie PKCS # 7 im C# -Code verwenden. Hier einige Code, der es richtig machen sollte:

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

Alternativ sollten Sie in der Lage sein, dies # Code in C zu setzen:

tdes.Padding = PaddingMode.Zeros; 

und haben auch sie arbeiten (wenn auch etwas weniger sicher).

2

Ich kenne PHP nicht, und ich habe auch Ihren C# -Code nicht sorgfältig analysiert, aber da der größte Teil der verschlüsselten Zeichenfolge identisch ist, ist vielleicht das Auffüllen der Daten der Unterschied? Vielleicht benutzt PHP einen anderen Modus als PaddingMode.PKCS7 im C# -Code? (Das wäre ein Kommentar gewesen, wenn ich dazu kommen könnte ...)

0

Als eine Randnotiz: Wenn Sie EZB verwenden, dann brauchen Sie keine IV. Tatsächlich ist die Verwendung von ECB die meiste Zeit ein Sicherheitsrisiko, so dass Sie wirklich etwas anderes verwenden müssen, z. CBC, die eine IV verwendet. Die IV ist ein zufälliger, nicht geheimer Wert mit der gleichen Größe wie die Verschlüsselungsblockgröße (8 Bytes für 3DES). Für jede Nachricht muss eine neue IV erstellt werden, und die entschlüsselnde Partei muss die IV kennen, die die verschlüsselnde Partei verwendet hat. In der Praxis wird die IV zusammen mit der verschlüsselten Nachricht gesendet.

Verwandte Themen