开发者

tripledes encryption not yielding same results in PHP and C#

开发者 https://www.devze.com 2022-12-23 13:28 出处:网络
When I encrypt with C# I get arTdPqWOg6VppOqUD6mGITjb24+x5vJjfAufNQ4DN7rVEtpDmhFnMeJGg4n5y1BN static void Main(string[] args)

When I encrypt with C# I get arTdPqWOg6VppOqUD6mGITjb24+x5vJjfAufNQ4DN7rVEtpDmhFnMeJGg4n5y1BN

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

When I encrypt with PHP I get: 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);
    ?>

I don't know enough about cryptography to figure out why. Any ideas? Thanks.


Peter is right. PHP just pads with zeros, while you're using PKCS#7 in the C# code. Here's some code that should do it right:

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

Alternatively, you should be able to put this in your C# code:

tdes.Padding = PaddingMode.Zeros;

and also have it work (albeit slightly less securely).


I don't know PHP, and neither have I analysed your C# code carefully, but as most of the encrypted string is the same maybe the padding of the data is the difference? Maybe PHP uses another mode than the PaddingMode.PKCS7 used in the C# code? (This would have been a comment if I could comment...)


As a side note: if you are using ECB then you do not need an IV. Actually, using ECB is most of the time a security hazard, so you really need to use something else, e.g. CBC, which uses an IV. The IV is a random, non-secret value with the same size than the cipher block size (8 bytes for 3DES). A new IV must be created for each message, and the decrypting party must know the IV that the encrypting party used. In practice, the IV is sent along with the encrypted message.

0

精彩评论

暂无评论...
验证码 换一张
取 消