use*_*113 18 php c# encryption decode mcrypt
我目前在解密由php mcrypt加密的邮件方面遇到了一些问题.php代码如下:
<?php
//$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
$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/>";
?>
Run Code Online (Sandbox Code Playgroud)
然后将加密的消息发送到ASP.NET平台(C#).但是,我在保留解密顺序(base64解码到urldecode)时遇到问题.我在ASP.NET中的代码如下(iv和key与php中的相同):
public string Decode(string str)
{
byte[] decbuff = Convert.FromBase64String(str);
return System.Text.Encoding.UTF8.GetString(decbuff);
}
static public String DecryptRJ256(string cypher, string KeyString, string IVString)
{
string sRet = "";
RijndaelManaged rj = new RijndaelManaged();
UTF8Encoding encoding = new UTF8Encoding();
try
{
//byte[] message = Convert.FromBase64String(cypher);
byte[] message = encoding.GetBytes(cypher);
byte[] Key = encoding.GetBytes(KeyString);
byte[] IV = encoding.GetBytes(IVString);
rj.Padding = PaddingMode.Zeros;
rj.Mode = CipherMode.CBC;
rj.KeySize = 256;
rj.BlockSize = 256;
rj.Key = Key;
rj.IV = IV;
MemoryStream ms = new MemoryStream(message);
using (CryptoStream cs = new CryptoStream(ms, rj.CreateDecryptor(Key, IV), CryptoStreamMode.Read))
{
using (StreamReader sr = new StreamReader(cs))
{
sRet = sr.ReadToEnd();
}
}
}
finally
{
rj.Clear();
}
return sRet;
}
string temp = DecryptRJ256(Server.UrlDecode(Decode(cypher)), keyString, ivString);
Run Code Online (Sandbox Code Playgroud)
时遇到的问题是,我收到从PHP加密的消息后,我将其转换成字节[],然后转换回UTF8编码的字符串,所以我可以urldecode它.然后我将结果提供给函数,在那里我将字符串转换回byte []并在解密过程中运行它.但是,我无法得到理想的结果......任何想法?
提前致谢.
kza*_*kza 31
在这里,我可以看到双方的问题.
请记住,编码时得到的不是字符串,而是字节数组.所以在PHP中你不需要urlencode cyphertext.
你只需要base64编码.当你打开base64_encode帮助时,你会看到
base64_encode使用base64对给定数据进行编码.此编码旨在使二进制数据在传输中幸存
还有一件事 - 要使用正确的长度在.net中解码您的消息,您必须手动使用填充字符附加它.RijndaelManaged的默认填充模式是PKCS7,让我们坚持下去.您必须将源字符串扩展为偶数块,其字符代码等于填充字节数.
<?php
$iv = "45287112549354892144548565456541";
$key = "anjueolkdiwpoida";
$text = "This is my encrypted message";
// to append string with trailing characters as for PKCS7 padding scheme
$block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
$padding = $block - (strlen($text) % $block);
$text .= str_repeat(chr($padding), $padding);
$crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $text, MCRYPT_MODE_CBC, $iv);
// this is not needed here
//$crypttext = urlencode($crypttext);
$crypttext64=base64_encode($crypttext);
print($crypttext64) . "\n<br/>";
?>
Run Code Online (Sandbox Code Playgroud)
在C#端,你可以从base64到byte []到string到byte [].您必须仅执行从base64到byte []的第一次转换.请记住,base64保存的是包含二进制数据的加密文本,而不是字符串.另请注意,RijndaelManaged是IDisposable,所以我将它包装在using()构造中.调用Close()是必要的,但不如MSDN中所述.
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();
}
}
}
finally
{
rj.Clear();
}
}
return sRet;
}
Run Code Online (Sandbox Code Playgroud)
因此,在C#中使用以下代码将返回初始字符串:
var iv = "45287112549354892144548565456541";
var key = "anjueolkdiwpoida";
var cypher = "u+rIlHB/2rrT/u/qFInnlEkg2unhizsNzGVb9O54sP8=";
var temp = DecryptRJ256(Decode(cypher), key, iv);
Run Code Online (Sandbox Code Playgroud)