Расшифровка в PHP строки в кодировке 3DES с помощью C # - PullRequest
0 голосов
/ 20 января 2012

Мне нужно расшифровать в PHP строку, закодированную этим классом C # (здесь )

using System;
using System.Security.Cryptography;
using System.Text;

public static class Encryption
{
   public static string Encrypt(string input, string key)
   {
      byte[] inputArray = UTF8Encoding.UTF8.GetBytes(input);
      TripleDESCryptoServiceProvider tripleDES = new TripleDESCryptoServiceProvider();
      tripleDES.Key = UTF8Encoding.UTF8.GetBytes(key);
      tripleDES.Mode = CipherMode.ECB;
      tripleDES.Padding = PaddingMode.PKCS7;
      ICryptoTransform cTransform = tripleDES.CreateEncryptor();
      byte[] resultArray = cTransform.TransformFinalBlock(inputArray, 0, inputArray.Length);
      tripleDES.Clear();
      return Convert.ToBase64String(resultArray, 0, resultArray.Length);
   }

   public static string Decrypt(string input, string key)
   {
      byte[] inputArray = Convert.FromBase64String(input);
      TripleDESCryptoServiceProvider tripleDES = new TripleDESCryptoServiceProvider();
      tripleDES.Key = UTF8Encoding.UTF8.GetBytes(key);
      tripleDES.Mode = CipherMode.ECB;
      tripleDES.Padding = PaddingMode.PKCS7;
      ICryptoTransform cTransform = tripleDES.CreateDecryptor();
      byte[] resultArray = cTransform.TransformFinalBlock(inputArray, 0, inputArray.Length);
      tripleDES.Clear();
      return UTF8Encoding.UTF8.GetString(resultArray);
   }
}

Я пробовал разные примеры, найденные в Интернете, но ничего не кажетсяработать.Я думаю, что первые проблемы возникают с параметром $ iv в php mcrypt_generic_init, а затем возникает другая проблема с заполнением, которое отсутствует в функциях php.Можете ли вы помочь мне преобразовать функцию расшифровки c # выше в PHP?Спасибо.

Ответы [ 2 ]

2 голосов
/ 14 марта 2015

Даже я сегодня пробовал код для PHP и C #

<?php
$key64 = "YOUR_KEY";
$iv64 = "YOUR_IV";


$keybytes = base64_decode($key64);
$ivbytes = base64_decode($iv64);

$text = ("4111111111111111");

// Padding the text
$padding = strlen($text)%8;
for($i=$padding; $i<8; $i++){
   $text .= chr(8-$padding);
}

$decryptRaw = mcrypt_encrypt(MCRYPT_3DES, $keybytes, $text, MCRYPT_MODE_CBC, $ivbytes);
$encoded = base64_encode($decryptRaw);

print "$encoded<br/>";
$encryptedString64 = $encoded;
$decryptbytes = base64_decode($encryptedString64);

$decryptRaw = mcrypt_decrypt(MCRYPT_3DES, $keybytes, $decryptbytes, MCRYPT_MODE_CBC, $ivbytes);
$decryptString=trim($decryptRaw,"\x00..\x1F");
print "$decryptString<br/>";

?>

C #

private string Decrypt(string encryptedValue)
{
    SymmetricAlgorithm tripleDESKey = SymmetricAlgorithm.Create("TripleDES") ;
    tripleDESKey.Key = Convert.FromBase64String("YOUR_KEY");
    tripleDESKey.IV = Convert.FromBase64String("YOUR_IV") ;

    MemoryStream encryptedStream = new MemoryStream();
    encryptedStream.Write(Convert.FromBase64String(encryptedValue), 0,
    Convert.FromBase64String(encryptedValue).Length);
    encryptedStream.Position = 0;
    CryptoStream cs = new CryptoStream(encryptedStream,
    tripleDESKey.CreateDecryptor(), CryptoStreamMode.Read);
    MemoryStream decryptedStream = new MemoryStream();

    byte[] buf = new byte[2049];
    int bytesRead = 0;
    bytesRead = cs.Read(buf, 0, buf.Length);
    while ((bytesRead > 0))
    {
        decryptedStream.Write(buf, 0, bytesRead);
        bytesRead = cs.Read(buf, 0, buf.Length);
    }
    return Encoding.ASCII.GetString(decryptedStream.ToArray());
}
private string Encrypt(string encrypt)
{
    SymmetricAlgorithm sa = SymmetricAlgorithm.Create("TripleDES") ;
    sa.Key = Convert.FromBase64String("YOUR_KEY");
    sa.IV = Convert.FromBase64String("YOUR_IV") ;
    byte[] inputByteArray = Encoding.ASCII.GetBytes(encrypt);
    MemoryStream mS = new MemoryStream();
    ICryptoTransform trans = sa.CreateEncryptor();
    byte[] buf = new byte[2049];
    CryptoStream cs = new CryptoStream(mS, trans, CryptoStreamMode.Write);
    cs.Write(inputByteArray, 0, inputByteArray.Length);
    cs.FlushFinalBlock();
    return Convert.ToBase64String(mS.ToArray());
}
2 голосов
/ 21 января 2012

Поскольку IV не имеет значения в режиме ECB, мы можем его игнорировать. Тем не менее, Mcrypt не очень снисходительно. Нам все еще нужно предоставить и IV, даже если это подделка.

// We'll be encrypting this data
    $key = 'password';
    $data = 'The quick brown fox jumped over the lazy dogs.';
    $encrypted = null;

// 3des in ECB mode
    $m = mcrypt_module_open(MCRYPT_3DES, null, MCRYPT_MODE_ECB, null);
// Our IV will be enough NUL bytes to satisfy mcrypt.
    $fake_iv = str_repeat(chr(0), mcrypt_enc_get_iv_size($m));
    mcrypt_generic_init($m, $key, $fake_iv);
    $encrypted = mcrypt_generic($m, $data);
// "s/6HOXpVyMyFdSPYUgIgneMRY0o3Kubkwc++hSg9kC4Sw0TWsNTqzrhXY3z4PH9w"
    echo base64_encode($encrypted), "\n";
    unset($m);

// And now, in reverse!
    $n = mcrypt_module_open(MCRYPT_3DES, null, MCRYPT_MODE_ECB, null);
// Another fake IV
    $fake_iv = str_repeat(chr(0), mcrypt_enc_get_iv_size($n));
    mcrypt_generic_init($n, $key, $fake_iv);
    $original = mdecrypt_generic($n, $encrypted);
// string(48) "The quick brown fox jumped over the lazy dogs."
    var_dump($original);

Опять же, вы захотите сделать это, только если будете придерживаться режима ECB. Режим ECB может быть довольно ужасным. Возможно, вы захотите просмотреть статью Википедии о режимах блочного шифрования для получения дополнительной информации.

Единственное, что здесь не обрабатывается, это отступы. mcrypt не позволяет вам выбрать метод заполнения и делает что-то другое в зависимости от шифра. Как правило, он не добавляет никаких отступов.

Если в выбранном вами методе заполнения используются байты NUL, вам необходимо предварительно заполнить данные самостоятельно, чтобы обеспечить совместимость. Вы можете использовать mcrypt_get_block_size и str_pad с опцией STR_PAD_RIGHT, чтобы сделать это.

Аналогичным образом, вам может потребоваться обрезать NUL-байты справа сразу после расшифровки. Поможет второй параметр trim.

...