1

我正在尝试在 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”。使用 DEC 库的 delphi 中的反向部分如下所示:

    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 Encryption Compendium library 5.1,它显然不符合 AEC。在我将代码升级到DEC 5.2库后一切正常。

4

1 回答 1

-1

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

因此,在您修复 TStringStream 的使用(切勿将其用于二进制数据)之后,检查两个库的代码或文档以了解如何处理关键数据 - 很可能它不直接用作密钥,而是用作“密码” ' 用于密钥派生过程。

于 2013-03-28T09:09:26.033 回答