无法使用使用PHP(Rijdael-128)加密的C#解密数据

无法使用使用PHP(Rijdael-128)加密的C#解密数据,c#,php,encryption,rijndael,C#,Php,Encryption,Rijndael,我使用以下代码使用PHP解密数据: $content="1234"; $cp = mcrypt_module_open('rijndael-128', '', 'cbc', ''); $iv = mcrypt_create_iv(16, MCRYPT_RAND); $key = pack("H*",md5('a')); mcrypt_generic_init($cp, $key, $iv); $encrypted = mcrypt_generic($cp, $content); echo bas

我使用以下代码使用PHP解密数据:

$content="1234";
$cp = mcrypt_module_open('rijndael-128', '', 'cbc', '');
$iv = mcrypt_create_iv(16, MCRYPT_RAND);
$key = pack("H*",md5('a'));
mcrypt_generic_init($cp, $key, $iv);
$encrypted = mcrypt_generic($cp, $content);
echo base64_encode($key)."\n";
echo base64_encode($iv)."\n";
echo base64_encode($encrypted)."\n";
mcrypt_generic_deinit($cp);
mcrypt_module_close($cp);
$iv和$encrypted然后保存到文件中,并在C#示例应用程序中读取:

var iv=...;
var encrypted=...;
var md5 = new MD5CryptoServiceProvider();
var key = md5.ComputeHash(Encoding.Default.GetBytes("a"));
md5.Clear();

Console.WriteLine(Convert.ToBase64String(key));
Console.WriteLine(Convert.ToBase64String(iv));
Console.WriteLine(Convert.ToBase64String(encrypted));
这里的输出与PHP的输出完全相同,因此我可以保证两者之间没有编码错误

var rd = new RijndaelManaged {
  Key = key,
  IV = iv,
  Mode = CipherMode.CBC,
  KeySize = 128,
  Padding = PaddingMode.Zeros
};

var buffer = new byte[encrypted.Length];
using(var ms = new MemoryStream(buffer)) {
  using(var cs = new CryptoStream(ms, rd.CreateDecryptor(), CryptoStreamMode.Write)) {
    cs.Write(encrypted, 0, encrypted.Length);
    ms.Read(buffer, 0, buffer.Length);
    Console.WriteLine(Encoding.Default.GetString(buffer));
  } 
}
rd.Clear();
解密的结果在每次程序启动时都会发生变化,即使输入数据完全相同:

首次运行:

dmf1ucdxtqgxw5niaxmyq==好吧,修改我过去罪恶的一个旧样本,我最终得出以下结论:

static string Decrypt() {            
  byte[] keyBytes = Convert.FromBase64String("DMF1ucDxtqgxw5niaXcmYQ==");
  byte[] iv = Convert.FromBase64String("GoCeRkrL/EMKNH/BYeLsqQ==");
  byte[] cipherTextBytes = Convert.FromBase64String("UBE3DkgbJgj1K/TISugLxA==");

  var symmetricKey = new RijndaelManaged { Mode = CipherMode.CBC, IV = iv, KeySize = 128, Key = keyBytes, Padding = PaddingMode.Zeros};

  using (var decryptor = symmetricKey.CreateDecryptor())
  using (var ms = new MemoryStream(cipherTextBytes))
  using (var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read)) {
    var plainTextBytes = new byte[cipherTextBytes.Length];
    int decryptedByteCount = cs.Read(plainTextBytes, 0, plainTextBytes.Length);
    return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount);
  }
}

其中给出了尾随\0个字符的“1234”。。您是不是又忘记将字节[]转换为字符串了?我还缺少什么不同之处?

解决方案非常简单,但大多数都很烦人。。。在设置“Key”属性之前,必须先设置“KeySize”属性。我一步一步地转换我的代码以匹配您的代码,当我切换两个setter时,它就工作了。如果有来自微软的人在听,您可以将这些信息包含到MSDN中。我知道,一旦你知道了,这是显而易见的,但是。。。本杰明,丹克!
static string Decrypt() {            
  byte[] keyBytes = Convert.FromBase64String("DMF1ucDxtqgxw5niaXcmYQ==");
  byte[] iv = Convert.FromBase64String("GoCeRkrL/EMKNH/BYeLsqQ==");
  byte[] cipherTextBytes = Convert.FromBase64String("UBE3DkgbJgj1K/TISugLxA==");

  var symmetricKey = new RijndaelManaged { Mode = CipherMode.CBC, IV = iv, KeySize = 128, Key = keyBytes, Padding = PaddingMode.Zeros};

  using (var decryptor = symmetricKey.CreateDecryptor())
  using (var ms = new MemoryStream(cipherTextBytes))
  using (var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read)) {
    var plainTextBytes = new byte[cipherTextBytes.Length];
    int decryptedByteCount = cs.Read(plainTextBytes, 0, plainTextBytes.Length);
    return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount);
  }
}