Rijndael在c#中加密文件,在Delphi中解密为字符串

本文关键字:解密 字符串 Delphi 文件 加密 Rijndael | 更新日期: 2023-09-27 18:06:26

我正在尝试加密c#中的文件,并将delphi中的内容解密为字符串。我尝试了几种设置,密钥/块大小和模式。目前c#端的代码是:

private void EncryptFile(string inputFile, string keyCode, string outputFile)
{
    try         {   
        byte[] key = Encoding.Unicode.GetBytes(keyCode);
        byte[] iv = new byte[16];
        Array.Copy(key, iv, 16);
        FileStream fsCrypt = new FileStream(outputFile, FileMode.Create);
        var RMCrypto = new AesManaged();
        RMCrypto.KeySize = 256;
        RMCrypto.BlockSize = 128;
        RMCrypto.Mode = CipherMode.ECB;
        CryptoStream cs = new CryptoStream(fsCrypt,
                                           RMCrypto.CreateEncryptor(key, iv),
                                           CryptoStreamMode.Write);
        FileStream fsIn = new FileStream(inputFile, FileMode.Open);
        int data;
        while ((data = fsIn.ReadByte()) != -1)
            cs.WriteByte((byte)data);
            
        fsIn.Close();
        cs.Close();
        fsCrypt.Close();
    }
    catch (Exception e)
    {
        MessageBox.Show(e.Message);
    }
}

关键参数为c#字符串"1234567887654321"。而在delphi中使用DEC库的反向部分是这样的:

    procedure TForm1.Button1Click(Sender: TObject);
var
  RCipher: TCipher_Rijndael;
  FileStream: TFileStream;
  StringStream: TStringStream;
  StringBytes: TBytes;
  Key: String;
begin
  Key := '1234567887654321';
  StringBytes := TEncoding.Unicode.GetBytes(Key);
  RCipher := TCipher_Rijndael.Create();
  FileStream := TFileStream.Create('C:'path'to'file.txt', fmOpenRead);
  StringStream := TStringStream.Create('', TEncoding.ANSI);
  RCipher.Init(StringBytes[0], 32, StringBytes[0], 16);
  RCipher.Mode := cmECBx;
  RCipher.DecodeStream(FileStream, StringStream, FileStream.Size);
  Memo1.Text := StringStream.DataString;
  RCipher.Free;
  FileStream.Free;
  StringStream.Free;
end;

但是我得到的都是随机字符…问题出在哪里?这些算法彼此不兼容吗?

编辑:将术语"中文字符"替换为"随机字符",以避免与unicode问题混淆。

多亏了pf1957,解决方案是意想不到的,但很简单。我正在使用Delphi加密汇编库5.1,这显然不是AEC兼容。在我将代码升级到DEC 5.2库之后,所有工作都很好。

Rijndael在c#中加密文件,在Delphi中解密为字符串

您正在使用16字节(128位)密钥数据,而您正在设置加密/解密器使用256位密钥。

所以,在你修复了TStringStream的用法之后(永远不要将它与二进制数据一起使用),检查代码或两个库的文档,以了解对密钥数据做了什么-最有可能的是它不是直接用作密钥,而是用作密钥派生过程的'密码'。