问题描述
下面是我的C#代码,解密C#中的编码字符串
Below is my C# code which decrypts the encoded string in C#.
RijndaelManaged RijndaelCipher = new RijndaelManaged();
string DecryptedData;
byte[] EncryptedData = Convert.FromBase64String(TextToBeDecrypted);
byte[] Salt = Encoding.ASCII.GetBytes(Password.Length.ToString());
//Making of the key for decryption
PasswordDeriveBytes SecretKey = new PasswordDeriveBytes(Password, Salt);
//Creates a symmetric Rijndael decryptor object.
ICryptoTransform Decryptor = RijndaelCipher.CreateDecryptor(SecretKey.GetBytes(32), SecretKey.GetBytes(16));
byte[] plainText = Decryptor.TransformFinalBlock(EncryptedData, 0, EncryptedData.Length);
//Converting to string
DecryptedData = Encoding.Unicode.GetString(plainText);
但我想以上的PHP相同的代码。我试图通过下面的代码,但它不给我正确的输出。
But I want above same code in PHP. I tried by below code but it is not giving me correct output.
function Decrypt( $encrypted, $key, $iv ){
$encrypted=base64_decode($encrypted);
return mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $encrypted, MCRYPT_MODE_CFB, $iv);
}
下面我得到的输出 $)íqyZiG¤õ ¡¹¡
我通过了 $ S ='cJ4ZJD3Vkf3Dv5uxrWiTQg =='
和 $键='123'
(这是一样的,而在C#加密使用)。
Here i am getting output $)íqyZiG¤õ¡¹¡
I passed $s = 'cJ4ZJD3Vkf3Dv5uxrWiTQg=='
and $key = '123'
(which is same, used while encrypting in C#).
我要传递给 $ IV
什么让我得到解密后的输出为 Snehal
What should I pass to $iv
so that I get the decrypted output as "Snehal
"?
推荐答案
首先你需要MCRYPT_RIJNDAEL_128不是256和CBC模式。但是,更大的问题是PasswordDeriveBytes。我不认为这是供PHP。但是......有一点工作的浏览MS源和单声道源就可以创建类似的
Firstly you need MCRYPT_RIJNDAEL_128 not 256 and CBC mode. But, the bigger problem is PasswordDeriveBytes. I don't think this is available for PHP. But... with a bit of work browsing MS source and Mono source it is possible to create something similar.
易位为:
<?php
$encb64 = "cJ4ZJD3Vkf3Dv5uxrWiTQg==";
$pwd = "123";
$salt = "3";
$enc = base64_decode($encb64);
$decpad = Decrypt($enc, $pwd, $salt);
// Remove the padding
$pad = ord($decpad[($len = strlen($decpad)) - 1]);
$dec = substr($decpad, 0, strlen($decpad) - $pad);
echo "Enc: " . bin2hex($enc) . "\r\n";
echo "Dec: " . $dec . "\r\n";
function Decrypt($ciphertext, $password, $salt)
{
$key = PBKDF1($password, $salt, 100, 32);
$iv = PBKDF1($password, $salt, 100, 16);
// NB: Need 128 not 256 and CBC mode to be compatible
return mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $ciphertext, MCRYPT_MODE_CBC, $iv);
}
?>
?>
然后使用PBKDF1功能从为出发点,看着两个单声道和微软源代码,我们可以得出与下面的功能。
Then using the PBKDF1 function from this post as a starting point and looking at both the Mono and Microsoft source we can come up with the function below.
请注意该警告。这是做事情的原因是多方面的一个非常糟糕的方式,但它足以说明如何实现什么要求。
PLEASE take note of the warnings. This is a VERY BAD way of doing things for many reasons but it is sufficient to show how to achieve what was asked.
<?php
function PBKDF1($pass, $salt, $count, $cb)
{
// This is very approximately the way that the Microsoft version of
// PasswordDeriveBytes works.
///
/// !!!WARNING!!!
///
// This is a BAD function!
// Irrespective of the fact that the use of PBKDF1 is not recommended anyway.
//
// This really should be put into a class with a constructor taking the
// $pass, $salt and $count.
// Then there should be a Reset() method to start from scratch each time a new pwd/salt is used.
// And there should be a GetBytes(int) method to get the required info.
// But for the sake of simplicity we are assuming the same pwd and salt for each call to
// this function. This will not stand up to any scrutiny!
static $base;
static $extra;
static $extracount= 0;
static $hashno;
static $state = 0;
if ($state == 0)
{
$hashno = 0;
$state = 1;
$key = $pass . $salt;
$base = sha1($key, true);
for($i = 2; $i < $count; $i++)
{
$base = sha1($base, true);
}
}
$result = "";
// Check if we have any bytes left over from a previous iteration.
// This is the way MS appears to do it. To me it looks very badly wrong
// in the line: "$result = substr($extra, $rlen, $rlen);"
// I'm sure it should be more like "$result = substr($extra, $extracount, $rlen);"
// Mono have provided what looks like a fixed version at
// https://github.com/mono/mono/blob/master/mcs/class/corlib/System.Security.Cryptography/PasswordDeriveBytes.cs
// But I'm no cryptographer so I might be wrong.
// But this seems to work for low values of $hashno and seems to work
// with C# implementations.
if ($extracount > 0)
{
$rlen = strlen($extra) - $extracount;
if ($rlen >= $cb)
{
$result = substr($extra, $extracount, $cb);
if ($rlen > $cb)
{
$extracount += $cb;
}
else
{
$extra = null;
$extracount = 0;
}
return $result;
}
$result = substr($extra, $rlen, $rlen);
}
$current = "";
$clen = 0;
$remain = $cb - strlen($result);
while ($remain > $clen)
{
if ($hashno == 0)
{
$current = sha1($base, true);
}
else if ($hashno < 1000)
{
$n = sprintf("%d", $hashno);
$tmp = $n . $base;
$current .= sha1($tmp, true);
}
$hashno++;
$clen = strlen($current);
}
// $current now holds at least as many bytes as we need
$result .= substr($current, 0, $remain);
// Save any left over bytes for any future requests
if ($clen > $remain)
{
$extra = $current;
$extracount = $remain;
}
return $result;
}
?>
这篇关于不同的结果在C#和PHP与Rijndael算法解密时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!