2010-03-18 48 views
5

当我用C#加密我得到arTdPqWOg6VppOqUD6mGITjb24+x5vJjfAufNQ4DN7rVEtpDmhFnMeJGg4n5y1BNTripleDes的加密没有产生在PHP和相同的结果,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); 
} 

当我用PHP加密我得到: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); 
    ?> 

我不知道够不够关于密码学来找出原因。有任何想法吗?谢谢。

+0

每个结果是否一致?至少对于哈希来说,我相信他们会生成一个随机盐。 – Jonah 2010-03-18 03:48:46

回答

6

彼得是对的。当您在C#代码中使用PKCS#7时,PHP只填充零。下面是一些代码,应该做的是正确的:

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

另外,你应该能够把这个在你的C#代码:

tdes.Padding = PaddingMode.Zeros; 

,也有它的工作(尽管略低于安全)。

2

我不知道PHP,也没有仔细分析你的C#代码,但由于大多数加密字符串是相同的,也许填充的数据是不同的?也许PHP使用另一种模式,而不是在C#代码中使用的PaddingMode.PKCS7? (如果我能发表评论,这将是一个评论...)

0

附注:如果您使用ECB,则不需要IV。实际上,使用ECB大部分时间都是安全隐患,所以你确实需要使用别的东西,例如CBC,使用IV。 IV是与密码块大小(3DES的8个字节)相同大小的随机非秘密值。必须为每条消息创建一个新的IV,并且解密方必须知道加密方使用的IV。实际上,IV与加密的消息一起发送。

相关问题