Расшифровка в PHP строки в кодировке 3DES с помощью C#
Я должен расшифровать в PHP строку, закодированную этим классом C# (это здесь)
используя Систему; использование System.Security.Cryptography; использование System.Text; открытый статический класс Encryption { открытая статическая строка Encrypt (строковый ввод, строковый ключ) { byte[] inputArray = UTF8Encoding.UTF8.GetBytes(input); TripleDESCryptoServiceProvider tripleDES = новый 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); } открытая статическая строка Decrypt (ввод строки, строковый ключ) { byte[] inputArray = Convert.FromBase64String(input); TripleDESCryptoServiceProvider tripleDES = новый 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 ответа
Даже я попробовал сегодня код для 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());
}
Поскольку 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
поможет.