我正在尝试在C#中重写此函数。但是C#输出与php不匹配
PHP版
// Encrypt data using AES128-cbc
function encrypt($data, $key, $iv) {
$cipher = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', 'cbc', '');
mcrypt_generic_init($cipher, $key, $iv);
$multipass = mcrypt_generic($cipher, $data);
mcrypt_generic_deinit($cipher);
return $multipass;
}
C#版本
public static string encrypt(string encryptionString, string iv, string key)
{
byte[] clearTextBytes = Encoding.UTF8.GetBytes(encryptionString);
var rijn = SymmetricAlgorithm.Create();
rijn.KeySize = 128;
rijn.Mode = CipherMode.CBC;
var ms = new MemoryStream();
var cs = new CryptoStream(ms, rijn.CreateEncryptor(Encoding.UTF8.GetBytes(key), Encoding.UTF8.GetBytes(iv)), CryptoStreamMode.Write);
cs.Write(clearTextBytes, 0, clearTextBytes.Length);
cs.Close();
var tmp = Encoding.UTF8.GetString(ms.ToArray());
return tmp;
}
答案 0 :(得分:6)
使用PHP加密/解密:
class Cipher {
private $key, $iv;
function __construct() {
$this->key = "edrtjfjfjlldldld";
$this->iv = "56666852251557009888889955123458";
}
function encrypt($text) {
$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, $this->key, $text, MCRYPT_MODE_CBC, $this->iv);
return base64_encode($crypttext);
}
function decrypt($input) {
$dectext = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $this->key, base64_decode($input), MCRYPT_MODE_CBC, $this->iv);
return $dectext;
}
}
使用C#加密/解密:
public class RijndaelSimple
{
const string iv = "56666852251557009888889955123458";
const string key = "edrtjfjfjlldldld";
static public String EncryptRJ256(string plainText)
{
var encoding = new UTF8Encoding();
var Key = encoding.GetBytes(key);
var IV = encoding.GetBytes(iv);
byte[] encrypted;
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();
using (var cs = new CryptoStream(ms, rj.CreateEncryptor(Key, IV), CryptoStreamMode.Write))
{
using (var sr = new StreamWriter(cs))
{
sr.Write(plainText);
sr.Flush();
cs.FlushFinalBlock();
}
encrypted = ms.ToArray();
}
}
finally
{
rj.Clear();
}
}
return Convert.ToBase64String(encrypted);
}
static public String DecryptRJ256(string input)
{
byte[] cypher = Convert.FromBase64String(input);
var sRet = "";
var encoding = new UTF8Encoding();
var Key = encoding.GetBytes(key);
var IV = encoding.GetBytes(iv);
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;
}
}
答案 1 :(得分:4)
C#代码存在两个问题。
您不应将MemoryStream
的内容编码为UTF8。 CryptoStream
的输出是二进制的,无法正确转换。要么返回byte[]
,要么确实需要字符串,请将输出编码为Hex或Base64。
您需要通过rijn.Padding = PaddingMode.Zeros;
设置填充模式。虽然没有明确说明,PHP使用0来填充数据块大小。 SymmetricAlgorithm
的填充默认值为PKCS7。
另请注意,PHP和C#方法的签名是不同的。 PHP函数的参数顺序为data, key, iv
,而C#方法为data, iv, key
。如果您在我上面列出的更改后仍然遇到问题,那么在调用C#加密方法时可能会反转您的IV和密钥。