我在两个平台上编写了相同的方法,我认为这些方法应该产生相同的结果,但它没有发生。我使用相同的密钥加密了相同的文本,结果不同。有人能弄清楚为什么会这样吗?
字符串:这是测试
键:1234567812345678
PHP 加密字符串: ybUaKwQlRNwOjJhxLWtLYQ==
C# 加密字符串: r2YjEFPyDDacnPmDFcGTLA==
C# 函数
static string Encrypt(string plainText, string key)
{
string cipherText;
var rijndael = new RijndaelManaged()
{
Key = Encoding.UTF8.GetBytes(key),
Mode = CipherMode.ECB,
BlockSize = 128,
};
ICryptoTransform encryptor = rijndael.CreateEncryptor(rijndael.Key, rijndael.IV);
using (var memoryStream = new MemoryStream())
{
using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
{
using (var streamWriter = new StreamWriter(cryptoStream))
{
streamWriter.Write(plainText);
streamWriter.Flush();
}
cipherText = Convert.ToBase64String(memoryStream.ToArray());
//cryptoStream.FlushFinalBlock();
}
}
return cipherText;
}
private static string Decrypt(string cipherText, string key)
{
string plainText;
byte[] cipherArray = Convert.FromBase64String(cipherText);
var rijndael = new RijndaelManaged()
{
Key = Encoding.UTF8.GetBytes(key),
Mode = CipherMode.ECB,
BlockSize = 128
};
ICryptoTransform decryptor = rijndael.CreateDecryptor(rijndael.Key, rijndael.IV);
using (var memoryStream = new MemoryStream(cipherArray))
{
using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
{
using (var streamReader = new StreamReader(cryptoStream))
{
plainText = streamReader.ReadToEnd();
}
}
}
return plainText;
}
PHP 函数
function string_encrypt($string, $key) {
$crypted_text = mcrypt_encrypt(
MCRYPT_RIJNDAEL_128,
$key,
$string,
MCRYPT_MODE_ECB
);
return base64_encode($crypted_text);
}
function string_decrypt($encrypted_string, $key) {
return mcrypt_decrypt(
MCRYPT_RIJNDAEL_128,
$key,
base64_decode($encrypted_string),
MCRYPT_MODE_ECB
);
}
我不太擅长 C#,我知道 PHP 函数工作正常。因此,必须对 C# 函数执行一些操作。可能是要加密的字符串应该转换为拉丁字符。
C# 默认使用 Rijndael 填充并使用 PKCS7。
这意味着您必须按照 PKCS7 填充 PHP 端,下面的代码应该可以工作:
function string_encrypt($string, $key) {
$block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB);
$padding = $block - (strlen($string) % $block);
$string .= str_repeat(chr($padding), $padding);
$crypted_text = mcrypt_encrypt(
MCRYPT_RIJNDAEL_128,
$key,
$string,
MCRYPT_MODE_ECB
);
return base64_encode($crypted_text);
}
有关更多信息,请参阅此处的第一个答案
我还应该补充一点,如果您想更改 C# 端而不使用填充,请进行以下修改并保留 PHP 端:
static string Encrypt(string plainText, string key)
{
string cipherText;
var rijndael = new RijndaelManaged()
{
Key = Encoding.UTF8.GetBytes(key),
Mode = CipherMode.ECB,
BlockSize = 128,
Padding = PaddingMode.Zeros,
};
ICryptoTransform encryptor = rijndael.CreateEncryptor(rijndael.Key, null);
using (var memoryStream = new MemoryStream())
{
using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
{
using (var streamWriter = new StreamWriter(cryptoStream))
{
streamWriter.Write(plainText);
streamWriter.Flush();
}
//cipherText = Convert.ToBase64String(Encoding.UTF8.GetBytes(Encoding.UTF8.GetString(memoryStream.ToArray())));
cipherText = Convert.ToBase64String(memoryStream.ToArray());
//cryptoStream.FlushFinalBlock();
}
}
return cipherText;
}