跨平台(php 到 C# .NET)encryption/decryption 与 Rijndael 第 2 部分
Cross platform (php to C# .NET) encryption/decryption with Rijndael Part 2
<Original Code From Here>
我在谷歌搜索时遇到了这个话题。但是在尝试和调整之后,我遇到了一个障碍,希望有人能帮助我。
上面的代码很好,但是如果不每次都更改 IV,该算法并不是很有用,我尝试使用以下代码生成 iv,但它一直在我的 "Specified key is not a valid size for this algorithm." C# 调试器。
我还尝试从 C# 代码输出 IV,在解码 base 64 字符串后,字符串长度从 30 31 2X 变化 ==> 基本上只是由于某种原因而波动。
我也想更改 KEY,但由于与 IV 问题类似的原因不能,所以希望有人能帮我解决这个问题吗?
(我已经尝试了 http://php.net/manual/en/function.mcrypt-encrypt.php 中的以下内容,无法使其与 C# 协调工作,也许一旦我解决了 IV 问题,我也能解决这个问题?
$key = pack('H*', "bcb04b7e103a0cd8b54763051cef08bc55abe029fdebae5e1d417e2ffb2a00a3"); )
PHP========================
<?php
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
//$iv = "45287112549354892144548565456541";
$key = "anjueolkdiwpoida";
$text = "This is my encrypted message";
$crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $text, MCRYPT_MODE_CBC, $iv);
$crypttext = urlencode($crypttext);
$crypttext64=base64_encode($crypttext);
print($crypttext64) . "\n<br/>";
print(base64encode($iv)) . "\n<br/>";
?>
C#========================
string iv = Encoding.UTF8.GetString(Convert.FromBase64String("SOME IV STRING I COPY FROM BROSWER WITH ABOVE PHP LOADED"));
string kyy = "anjueolkdiwpoida";
//ciphertext is also SOME TXT STRING I COPIED FROM BROWSER WITH ABOVE PHP LOADED
string plainText = ValidationControls.DecryptRJ256(cipherText, kyy, iv);
public byte[] Decode(string str)
{
var decbuff = Convert.FromBase64String(str);
return decbuff;
}
static public String DecryptRJ256(byte[] cypher, string KeyString, string IVString)
{
var sRet = "";
var encoding = new UTF8Encoding();
var Key = encoding.GetBytes(KeyString);
var IV = encoding.GetBytes(IVString);
using (var rj = new RijndaelManaged())
{
try
{
rj.Padding = PaddingMode.PKCS7;
rj.Mode = CipherMode.CBC;
rj.KeySize = 256;
rj.BlockSize = 256;
rj.Key = Key;
rj.IV = IV;
var ms = new MemoryStream(cypher);
using (var cs = new CryptoStream(ms, rj.CreateDecryptor(Key, IV), CryptoStreamMode.Read))
{
using (var sr = new StreamReader(cs))
{
sRet = sr.ReadLine();
}
}
}
catch (Exception exc) { Console.WriteLine(exc.Message); App.Current.Shutdown(); }
finally
{
rj.Clear();
}
}
return sRet;
}
我意识到 .NET 对 Base 64 字符串的解码真的很奇怪。当我调用 DecryptRJ256() 时,我发送了通过一系列转换 base64_string -> byte -> utf8_string 从 php 代码收到的密钥和 IV,然后将它们发送到功能。解决办法就是直接把字节数组传进来,让DecryptRJ256()直接处理。
完成上述操作后,自动生成密钥和 IV 的问题变得明显,不再是问题。
根据问题修改的代码:
PHP
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$key = pack('H*', "bcb04b7e103a0cd8b54763051cef08bc55abe029fdebae5e1d417e2ffb2a00a3");
$text = "This is my encrypted message";
$crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $text, MCRYPT_MODE_CBC, $iv);
$crypttext = base64_encode($crypttext);
$key= base64_encode($key);
$iv = base64_encode($iv);
C#
string plainText = ValidationControls.DecryptRJ256(Convert.FromBase64String("/*$CRYPTTEXT STRING FROM PHP*/"), Convert.FromBase64String("/*$KEY STRING FROM PHP*/"), Convert.FromBase64String("/*$ STRING FROM PHP*/"));
static public String DecryptRJ256(byte[] cypher, byte[] KeyString, byte[] IVString)
{
...
var Key = KeyString;
//var Key = encoding.GetBytes(KeyString);
var IV = IVString;
//var IV = encoding.GetBytes(IVString);
...
}
<Original Code From Here>
我在谷歌搜索时遇到了这个话题。但是在尝试和调整之后,我遇到了一个障碍,希望有人能帮助我。
上面的代码很好,但是如果不每次都更改 IV,该算法并不是很有用,我尝试使用以下代码生成 iv,但它一直在我的 "Specified key is not a valid size for this algorithm." C# 调试器。
我还尝试从 C# 代码输出 IV,在解码 base 64 字符串后,字符串长度从 30 31 2X 变化 ==> 基本上只是由于某种原因而波动。
我也想更改 KEY,但由于与 IV 问题类似的原因不能,所以希望有人能帮我解决这个问题吗?
(我已经尝试了 http://php.net/manual/en/function.mcrypt-encrypt.php 中的以下内容,无法使其与 C# 协调工作,也许一旦我解决了 IV 问题,我也能解决这个问题?
$key = pack('H*', "bcb04b7e103a0cd8b54763051cef08bc55abe029fdebae5e1d417e2ffb2a00a3"); )
PHP========================
<?php
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
//$iv = "45287112549354892144548565456541";
$key = "anjueolkdiwpoida";
$text = "This is my encrypted message";
$crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $text, MCRYPT_MODE_CBC, $iv);
$crypttext = urlencode($crypttext);
$crypttext64=base64_encode($crypttext);
print($crypttext64) . "\n<br/>";
print(base64encode($iv)) . "\n<br/>";
?>
C#========================
string iv = Encoding.UTF8.GetString(Convert.FromBase64String("SOME IV STRING I COPY FROM BROSWER WITH ABOVE PHP LOADED"));
string kyy = "anjueolkdiwpoida";
//ciphertext is also SOME TXT STRING I COPIED FROM BROWSER WITH ABOVE PHP LOADED
string plainText = ValidationControls.DecryptRJ256(cipherText, kyy, iv);
public byte[] Decode(string str)
{
var decbuff = Convert.FromBase64String(str);
return decbuff;
}
static public String DecryptRJ256(byte[] cypher, string KeyString, string IVString)
{
var sRet = "";
var encoding = new UTF8Encoding();
var Key = encoding.GetBytes(KeyString);
var IV = encoding.GetBytes(IVString);
using (var rj = new RijndaelManaged())
{
try
{
rj.Padding = PaddingMode.PKCS7;
rj.Mode = CipherMode.CBC;
rj.KeySize = 256;
rj.BlockSize = 256;
rj.Key = Key;
rj.IV = IV;
var ms = new MemoryStream(cypher);
using (var cs = new CryptoStream(ms, rj.CreateDecryptor(Key, IV), CryptoStreamMode.Read))
{
using (var sr = new StreamReader(cs))
{
sRet = sr.ReadLine();
}
}
}
catch (Exception exc) { Console.WriteLine(exc.Message); App.Current.Shutdown(); }
finally
{
rj.Clear();
}
}
return sRet;
}
我意识到 .NET 对 Base 64 字符串的解码真的很奇怪。当我调用 DecryptRJ256() 时,我发送了通过一系列转换 base64_string -> byte -> utf8_string 从 php 代码收到的密钥和 IV,然后将它们发送到功能。解决办法就是直接把字节数组传进来,让DecryptRJ256()直接处理。
完成上述操作后,自动生成密钥和 IV 的问题变得明显,不再是问题。
根据问题修改的代码:
PHP
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$key = pack('H*', "bcb04b7e103a0cd8b54763051cef08bc55abe029fdebae5e1d417e2ffb2a00a3");
$text = "This is my encrypted message";
$crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $text, MCRYPT_MODE_CBC, $iv);
$crypttext = base64_encode($crypttext);
$key= base64_encode($key);
$iv = base64_encode($iv);
C#
string plainText = ValidationControls.DecryptRJ256(Convert.FromBase64String("/*$CRYPTTEXT STRING FROM PHP*/"), Convert.FromBase64String("/*$KEY STRING FROM PHP*/"), Convert.FromBase64String("/*$ STRING FROM PHP*/"));
static public String DecryptRJ256(byte[] cypher, byte[] KeyString, byte[] IVString)
{
...
var Key = KeyString;
//var Key = encoding.GetBytes(KeyString);
var IV = IVString;
//var IV = encoding.GetBytes(IVString);
...
}