然后将加密的消息发送到 ASP.NET 平台 (C#)。但是,我在保留解密顺序时遇到问题(base64 解-6ren">
gpt4 book ai didi

c# - 使用 Rijndael 进行跨平台(php 到 C# .NET)加密/解密

转载 作者:IT王子 更新时间:2023-10-29 00:07:08 26 4
gpt4 key购买 nike

我目前在解密由 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/>";
?>

然后将加密的消息发送到 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);

我遇到的问题是,在收到来自 php 的加密消息后,我将其转换为 byte[],然后再转换回 UTF8 编码的字符串,以便我可以对它进行 urldecode。然后我将结果输入函数,在该函数中我将字符串转换回 byte[] 并通过解密过程运行它。但是,我得不到想要的结果……有什么想法吗?

提前致谢。

最佳答案

在这里我可以看到双方的问题。

请记住,编码时得到的不是字符串,而是字节数组。所以在 PHP 中你不需要对密文进行 urlencode。

base64 编码就是您所需要的。当你打开 base64_encode help 时,你会看到

base64_encode Encodes the given data with base64. This encoding is designed to make binary data survive transport

还有一件事 - 要在 .net 中以正确的长度解码您的消息,您必须手动附加填充字符。 RijndaelManaged 的​​默认填充模式是 PKCS7,让我们坚持使用它。您必须将源字符串扩展到字符代码等于填充字节数的偶数 block 。

<?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/>";
?>

在 C# 端,您可以从 base64 转换为 byte[],再转换为 string,再转换为 byte[]。您必须只进行从 base64byte[] 的第一次转换。请记住,base64 保存的是二进制数据的加密文本,而不是字符串。另请注意,RijndaelManaged 是 IDisposable,因此我将其包装在 using() 结构中。如 MSDN 中所述,调用 Close() 是必要的,但还不够。

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;
}

因此,C# 中的以下代码将返回初始字符串:

var iv = "45287112549354892144548565456541";
var key = "anjueolkdiwpoida";
var cypher = "u+rIlHB/2rrT/u/qFInnlEkg2unhizsNzGVb9O54sP8=";

var temp = DecryptRJ256(Decode(cypher), key, iv);

关于c# - 使用 Rijndael 进行跨平台(php 到 C# .NET)加密/解密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4329260/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com