复制加密算法

本文关键字:加密算法 复制 | 更新日期: 2023-09-27 18:04:22

(我试着在Cryptography Stack Exchange上问这个问题,他们觉得不合适)

我试图复制在Delphi c#中编写的算法,最好使用标准的。net库。假定德尔菲算法通过了标准的参考测试。应该是AES/CBC;但是,我无法用System.Security.Cryptography.AesManaged.

复制结果。

使用简单输入调用它的示例:

function StringToHex(S: string): string;
var
  i: integer;
begin
  Result := '';
  for i := 1 to Length(S) do
    Result := Result + IntToHex(Ord(S[i]), 2);
end;
var
  PlainText:     AnsiString;
  AES:           TAES;
  Key:           TAESKey256;  // array[0..31] of byte;
  InitialVector: TAESBuffer;  // array[0..15] of byte;
  InputStream:   TStringStream;
  OutputStream:  TStringStream;
begin
  PlainText := 'test';
  FillChar(Key, SizeOf(Key), 1);
  FillChar(InitialVector, SizeOf(InitialVector), 2);
  AES          := TAES.Create;
  InputStream  := TStringStream.Create(PlainText);
  OutputStream := TStringStream.Create('');
  try
    AES.EncryptAESStreamCBC(InputStream, 0, Key, InitialVector, OutputStream);
    Writeln(StringToHex(OutputStream.DataString));
    Readln;
  finally
    InputStream.Free;
    OutputStream.Free;
    AES.Free;
  end;
end.
输出:

CEE3684F05D02E5A0930CED21F76075A

代码似乎是基于Delphi Spring框架。

我如何在。net中复制这个?

我所尝试的(甚至切换到字节以避免任何Unicode问题):

public byte[] Encrypt()
{
    using (var algorithm = new AesManaged())
    {
        // Default is CBC
        algorithm.Key = Enumerable.Repeat((byte)0x01, 32).ToArray();
        algorithm.IV = Enumerable.Repeat((byte)0x02, 16).ToArray();
        using (ICryptoTransform encryptor = algorithm.CreateEncryptor(algorithm.Key, algorithm.IV))
        {
            using (var stream = new MemoryStream())
            {
                using (var cryptoStream = new CryptoStream(stream, encryptor, CryptoStreamMode.Write))
                {
                    using (var writer = new BinaryWriter(cryptoStream))
                    {
                        writer.Write(new byte[] {0x74, 0x65, 0x73, 0x74});
                    }
                    return stream.ToArray();
                }
            }
        }
    }
}

这会导致不同的输出(第一个字节是x6D)。

在其他任务中,他提到c#的默认设置:

BlockSize = 128;
Mode = System.Security.Cryptography.CipherMode.CBC;
Padding = System.Security.Cryptography.PaddingMode.PKCS7

在Delphi中,我看不到任何改变PaddingMode的选项,我猜它用零填充。如果它是正确的,那么你应该将c#中的padding改为

System.Security.Cryptography.PaddingMode.Zeros

(对不起,不能核实,这只是假设)

更新:正如shunty提到的,它可以工作,只需添加行:

algorithm.Padding = PaddingMode.Zeros;

复制加密算法

如果你想在Delphi中使用Spring框架的功能,我的建议是使用Delphi创建一个Win32 [Library] DLL并在你的。net应用程序中使用该DLL。这听起来比用c#重写代码(重新发明轮子?)更合乎逻辑。

你确定TStringStream返回AnsiString 'test'正好4个字节吗?多字节编码和/或零终止将导致另一个纯文本字节数组,而不是c#代码中使用的。