2

我正在尝试使用 DEC v5.2 在 Delphi 上加密/解密一些代码,并在 C# 上加密/解密。这个想法是使用 AES128。

在德尔福我有以下内容:

var
 ACipherClass: TDECCipherClass = TCipher_Rijndael;
 ACipherMode: TCipherMode = cmCBCx;
 ACipherFormat: TDECFormatClass = TFormat_MIME64;
 AHashClass: TDECHashClass = THash_MD5;
 AHashFormat: TDECFormatClass = TFormat_HEX;

function Encrypt(const AText: AnsiString; const APassword: AnsiString): AnsiString;
var
  AData, APass: Binary;
begin
  with ValidCipher(ACipherClass).Create, Context do
    try
      APass := ValidHash(AHashClass).CalcBinary(APassword,AHashFormat);
      Mode := ACipherMode;
      Init(APass);
      AData:=EncodeBinary(AText,ACipherFormat);
      Done;
      Result:=AData;
    finally
      Free;
      ProtectBinary(AData);
      ProtectBinary(APass);
    end;
end;

在 C# 上,我有:

static public string Encrypt(string data, string key)
{
    using (var crypt = new Crypt2())
    {
        crypt.UnlockComponent("LICENSE_IS_HERE");

        crypt.CryptAlgorithm = "aes";
        crypt.CipherMode = "cbc";
        crypt.KeyLength = 128;

        //  Generate a binary secret key from a password string
        //  of any length.  For 128-bit encryption, GenEncodedSecretKey
        //  generates the MD5 hash of the password and returns it
        //  in the encoded form requested.  The 2nd param can be
        //  "hex", "base64", "url", "quoted-printable", etc.
        var hexKey = crypt.GenEncodedSecretKey(key,"hex");
        crypt.SetEncodedKey(hexKey,"hex");

        crypt.EncodingMode = "base64";

        crypt.Charset = "ansi";

        return crypt.EncryptStringENC(data);
    }
}

但生成的代码并不相似。我究竟做错了什么 ?我错过了什么吗?

4

3 回答 3

2

检查两边的填充方法。AES 加密本身是标准的,但是当明文不是块长度的倍数时,不同的库使用不同的(默认)填充方法。我让它在 C# 端使用空填充,并且 a) 使用带有手动 #0 填充的 DCPCrypt(DCPCrypt 不做填充)和 b) Turbopower LockBox 3,作者 Sean Durkin 对其代码进行了扩展以处理C# 空填充。

旧 D2007 测试代码,按“原样”提供:

========== TPLB3 pas文件==============

unit uEncDecTests_LockBox;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Buttons, uTPLb_BaseNonVisualComponent,
  uTPLb_Codec, uTPLb_CryptographicLibrary;

type
  TFrmEncDecTests = class(TForm)
    EdtPlainText1: TEdit;
    EdtCypher: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    EdtPlainText2: TEdit;
    Label3: TLabel;
    Label4: TLabel;
    BiBEncrypt: TBitBtn;
    BiBDecrypt: TBitBtn;
    Label5: TLabel;
    EdtKey: TEdit;
    Label6: TLabel;
    EdtCypher64: TEdit;
    EdtIV: TEdit;
    Label7: TLabel;
    Label8: TLabel;
    EdtCypherHex: TEdit;
    AESCodec: TCodec;
    CryptographicLibrary1: TCryptographicLibrary;
    BtnInit: TButton;
    procedure BiBEncryptClick(Sender: TObject);
    procedure BiBDecryptClick(Sender: TObject);
    procedure BtnInitClick(Sender: TObject);
  private
    FOut: String;
  public
    { Public declarations }
  end;

var
  FrmEncDecTests: TFrmEncDecTests;

implementation

{$R *.dfm}

procedure TFrmEncDecTests.BiBDecryptClick(Sender: TObject);
var lPlainText: String;
begin
  AESCodec.DecryptString(FOut,lPlainText);
  EdtPlainText2.Text := lPlainText;
end;

procedure TFrmEncDecTests.BiBEncryptClick(Sender: TObject);
var
  lPlainText,
  sb,sh: String;
  b,o  : byte;
begin
  lPlainText := EdtPlaintext1.Text;
  AESCodec.EncryptString(lPlainText,FOut);
  sh := '';
  sb := '';
  for B := 0 to Length(FOut) do begin
    o := Ord(FOut[b]);
    sh := sh + IntToHex(o,2) + ' ';
    if o < 10 then sb := sb + '0';
    if o < 100 then sb := sb + '0';
    sb := sb + inttostr(o) + ' ';
  end;
  EdtCypher.Text := FOut;
  EdtCypher64.Text := sb;
  EdtCypherHex.Text := sh;
end;

procedure TFrmEncDecTests.BtnInitClick(Sender: TObject);
var
  p : PChar;
  MS: TMemoryStream;
begin
  p := pChar(EdtKey.Text);
  MS := TMemoryStream.Create;
  MS.Write(P^,Length(EdtKey.Text));
  MS.Seek(soFromBeginning,0);
  AESCodec.InitFromStream(MS);
  MS.Free;
  BiBEncrypt.Enabled := true;
  BiBDecrypt.Enabled := true;
end;

end.

========== TPLB3 dfm 文件 ===============

object FrmEncDecTests: TFrmEncDecTests
  Left = 0
  Top = 0
  Caption = 'Encryptie/decryptie tests (LockBox)'
  ClientHeight = 328
  ClientWidth = 535
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object Label1: TLabel
    Left = 16
    Top = 150
    Width = 114
    Height = 13
    Caption = 'Cyphertext (raw bytes)'
  end
  object Label2: TLabel
    Left = 16
    Top = 102
    Width = 46
    Height = 13
    Caption = 'Plaintext:'
  end
  object Label3: TLabel
    Left = 16
    Top = 280
    Width = 46
    Height = 13
    Caption = 'Plaintext:'
  end
  object Label4: TLabel
    Left = 16
    Top = 16
    Width = 22
    Height = 13
    Caption = 'Key:'
  end
  object Label5: TLabel
    Left = 339
    Top = 16
    Width = 182
    Height = 13
    Caption = 'Testing LockBox 3  AES-256, CBC'
    Font.Charset = DEFAULT_CHARSET
    Font.Color = clWindowText
    Font.Height = -11
    Font.Name = 'Tahoma'
    Font.Style = [fsBold]
    ParentFont = False
  end
  object Label6: TLabel
    Left = 16
    Top = 189
    Width = 101
    Height = 13
    Caption = 'Cyphertext (Base64)'
  end
  object Label7: TLabel
    Left = 16
    Top = 59
    Width = 14
    Height = 13
    Caption = 'IV:'
  end
  object Label8: TLabel
    Left = 17
    Top = 230
    Width = 85
    Height = 13
    Caption = 'Cyphertext (Hex)'
  end
  object EdtPlainText1: TEdit
    Left = 16
    Top = 118
    Width = 505
    Height = 21
    TabOrder = 0
    Text = 'somethingorother'
  end
  object EdtCypher: TEdit
    Left = 16
    Top = 166
    Width = 505
    Height = 21
    TabOrder = 1
  end
  object EdtPlainText2: TEdit
    Left = 16
    Top = 296
    Width = 505
    Height = 21
    TabOrder = 2
  end
  object BiBEncrypt: TBitBtn
    Left = 368
    Top = 141
    Width = 73
    Height = 23
    Caption = 'Encrypt'
    Enabled = False
    TabOrder = 3
    OnClick = BiBEncryptClick
    Glyph.Data = {
      76010000424D7601000000000000760000002800000020000000100000000100
      04000000000000010000120B0000120B00001000000000000000000000000000
      800000800000008080008000000080008000808000007F7F7F00BFBFBF000000
      FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFFFF00333333333333
      333333333333333333333333333333333333333333333333FFF3333333333333
      00333333333333FF77F3333333333300903333333333FF773733333333330099
      0333333333FF77337F3333333300999903333333FF7733337333333700999990
      3333333777333337F3333333099999903333333373F333373333333330999903
      33333333F7F3337F33333333709999033333333F773FF3733333333709009033
      333333F7737737F3333333709073003333333F77377377F33333370907333733
      33333773773337333333309073333333333337F7733333333333370733333333
      3333377733333333333333333333333333333333333333333333}
    NumGlyphs = 2
  end
  object BiBDecrypt: TBitBtn
    Left = 368
    Top = 270
    Width = 73
    Height = 23
    Caption = 'Decrypt'
    Enabled = False
    TabOrder = 4
    OnClick = BiBDecryptClick
    Glyph.Data = {
      76010000424D7601000000000000760000002800000020000000100000000100
      04000000000000010000120B0000120B00001000000000000000000000000000
      800000800000008080008000000080008000808000007F7F7F00BFBFBF000000
      FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFFFF00333333333333
      33333333333333333333333333333333333333FF333333333333300333333333
      33333773FF33333333333090033333333333373773FF33333333330990033333
      3333337F3773FF33333333099990033333333373F33773FFF333333099999007
      33333337F33337773333333099999903333333373F3333733333333309999033
      333333337F3337F333333333099990733333333373F3F77F3333333330900907
      3333333337F77F77F33333333003709073333333377377F77F33333337333709
      073333333733377F77F33333333333709033333333333377F7F3333333333337
      0733333333333337773333333333333333333333333333333333}
    NumGlyphs = 2
  end
  object EdtKey: TEdit
    Left = 16
    Top = 32
    Width = 265
    Height = 21
    TabOrder = 5
    Text = '12345678912345678912345678912345'
  end
  object EdtCypher64: TEdit
    Left = 16
    Top = 205
    Width = 505
    Height = 21
    TabOrder = 6
  end
  object EdtIV: TEdit
    Left = 16
    Top = 75
    Width = 265
    Height = 21
    TabOrder = 7
    Text = '1234567891234567'
  end
  object EdtCypherHex: TEdit
    Left = 17
    Top = 246
    Width = 505
    Height = 21
    TabOrder = 8
  end
  object BtnInit: TButton
    Left = 336
    Top = 80
    Width = 75
    Height = 25
    Caption = 'Init enc'
    TabOrder = 9
    OnClick = BtnInitClick
  end
  object AESCodec: TCodec
    AsymetricKeySizeInBits = 2048
    AdvancedOptions2 = []
    CryptoLibrary = CryptographicLibrary1
    Left = 336
    Top = 40
    StreamCipherId = 'native.StreamToBlock'
    BlockCipherId = 'native.AES-256'
    ChainId = 'native.CBC'
  end
  object CryptographicLibrary1: TCryptographicLibrary
    Left = 384
    Top = 40
  end
end

========== DCPCrypt 密码文件 ==============

unit uEncDecTests_DCPCrypt;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Buttons, LbCipher, LbClass, DCPcrypt2, DCPblockciphers,
  DCPrijndael;

const
  cOutBufSize = 1024;

type
  TFrmEncDecTests = class(TForm)
    EdtPlainText1: TEdit;
    EdtCypher: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    EdtPlainText2: TEdit;
    Label3: TLabel;
    Label4: TLabel;
    BiBEncrypt: TBitBtn;
    BiBDecrypt: TBitBtn;
    Label5: TLabel;
    EdtKey: TEdit;
    Label6: TLabel;
    EdtCypher64: TEdit;
    EdtIV: TEdit;
    Label7: TLabel;
    Label8: TLabel;
    EdtCypherHex: TEdit;
    BtnKAT: TButton;
    DCP_rijndael1: TDCP_rijndael;
    BtnHexConvert: TButton;
    procedure BiBEncryptClick(Sender: TObject);
    procedure BiBDecryptClick(Sender: TObject);
    procedure BtnKATClick(Sender: TObject);
    procedure BtnHexConvertClick(Sender: TObject);
  private
  public
  end;

var
  FrmEncDecTests: TFrmEncDecTests;

implementation

{$R *.dfm}

Uses
  DCPbase64,
  uRijndael,
  uKATVectors, uHexConvert;

procedure TFrmEncDecTests.BiBEncryptClick(Sender: TObject);
type
  KeyBuffer  = Array[1..32] of Byte;
  IVBuffer   = Array[1..16] of Byte;
var
  KeyHex, IVHex, PlainTxt, PlainHex, CypherStr, CypherHex, CypherB64, CypherBytes: String;
  i   : Integer;
begin
  KeyHex      := EdtKey.Text;
  IVHex       := EdtIV.Text;
  PlainTxt    := EdtPlainText1.Text;
  PlainHex    := StringToHex(PlainTxt);
  CypherHex   := RijndaelEncryptHex(KeyHex, IVHex, PlainHex);
  CypherStr   := HexToString(CypherHex);
  CypherB64   := Base64EncodeStr(CypherStr);
  CypherBytes := '';
  CypherBytes := '';  for i := 1 to Length(CypherStr) do CypherBytes := CypherBytes + IntToStr(Ord(CypherStr[i])) + ' ';
  EdtCypherHex.Text := CypherHex;
  EdtCypher.Text    := CypherBytes;
  EdtCypher64.Text  := CypherB64;
end;

procedure TFrmEncDecTests.BiBDecryptClick(Sender: TObject);
var
  KeyHex, IVHex, PlainHex: String;
begin
  KeyHex   := EdtKey.Text;
  IVHex    := EdtIV.Text;
  PlainHex := RijndaelDecryptHex(KeyHex,IVHex,EdtCypherHex.Text);
  EdtPlainText2.Text := HexToString(PlainHex);
end;

procedure TFrmEncDecTests.BtnHexConvertClick(Sender: TObject);
begin
  FrmHexConvert.ShowModal;
end;

procedure TFrmEncDecTests.BtnKATClick(Sender: TObject);
begin
   FrmKATVectors.ShowModal;
end;

end.

========== DCPCrypt dfm 文件 ===============

object FrmEncDecTests: TFrmEncDecTests
  Left = 0
  Top = 0
  Caption = 'Encryptie/decryptie tests (DCPCrypt)'
  ClientHeight = 328
  ClientWidth = 535
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object Label1: TLabel
    Left = 16
    Top = 150
    Width = 114
    Height = 13
    Caption = 'Cyphertext (raw bytes)'
  end
  object Label2: TLabel
    Left = 16
    Top = 102
    Width = 129
    Height = 13
    Caption = 'Plaintext (readable string):'
  end
  object Label3: TLabel
    Left = 16
    Top = 280
    Width = 46
    Height = 13
    Caption = 'Plaintext:'
  end
  object Label4: TLabel
    Left = 16
    Top = 16
    Width = 78
    Height = 13
    Caption = 'Key (hexstring):'
  end
  object Label5: TLabel
    Left = 301
    Top = 16
    Width = 232
    Height = 13
    Caption = 'Testing DCPCrypt Rijndael (key 256, CBC)'
    Font.Charset = DEFAULT_CHARSET
    Font.Color = clWindowText
    Font.Height = -11
    Font.Name = 'Tahoma'
    Font.Style = [fsBold]
    ParentFont = False
  end
  object Label6: TLabel
    Left = 16
    Top = 189
    Width = 101
    Height = 13
    Caption = 'Cyphertext (Base64)'
  end
  object Label7: TLabel
    Left = 16
    Top = 59
    Width = 70
    Height = 13
    Caption = 'IV (hexstring):'
  end
  object Label8: TLabel
    Left = 17
    Top = 230
    Width = 85
    Height = 13
    Caption = 'Cyphertext (Hex)'
  end
  object EdtPlainText1: TEdit
    Left = 16
    Top = 118
    Width = 505
    Height = 21
    TabOrder = 0
    Text = 'timetellbvencryptiemethode'
  end
  object EdtCypher: TEdit
    Left = 16
    Top = 166
    Width = 505
    Height = 21
    TabOrder = 1
  end
  object EdtPlainText2: TEdit
    Left = 16
    Top = 296
    Width = 505
    Height = 21
    TabOrder = 2
  end
  object BiBEncrypt: TBitBtn
    Left = 368
    Top = 141
    Width = 73
    Height = 23
    Caption = 'Encrypt'
    TabOrder = 3
    OnClick = BiBEncryptClick
    Glyph.Data = {
      76010000424D7601000000000000760000002800000020000000100000000100
      04000000000000010000120B0000120B00001000000000000000000000000000
      800000800000008080008000000080008000808000007F7F7F00BFBFBF000000
      FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFFFF00333333333333
      333333333333333333333333333333333333333333333333FFF3333333333333
      00333333333333FF77F3333333333300903333333333FF773733333333330099
      0333333333FF77337F3333333300999903333333FF7733337333333700999990
      3333333777333337F3333333099999903333333373F333373333333330999903
      33333333F7F3337F33333333709999033333333F773FF3733333333709009033
      333333F7737737F3333333709073003333333F77377377F33333370907333733
      33333773773337333333309073333333333337F7733333333333370733333333
      3333377733333333333333333333333333333333333333333333}
    NumGlyphs = 2
  end
  object BiBDecrypt: TBitBtn
    Left = 368
    Top = 270
    Width = 73
    Height = 23
    Caption = 'Decrypt'
    TabOrder = 4
    OnClick = BiBDecryptClick
    Glyph.Data = {
      76010000424D7601000000000000760000002800000020000000100000000100
      04000000000000010000120B0000120B00001000000000000000000000000000
      800000800000008080008000000080008000808000007F7F7F00BFBFBF000000
      FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFFFF00333333333333
      33333333333333333333333333333333333333FF333333333333300333333333
      33333773FF33333333333090033333333333373773FF33333333330990033333
      3333337F3773FF33333333099990033333333373F33773FFF333333099999007
      33333337F33337773333333099999903333333373F3333733333333309999033
      333333337F3337F333333333099990733333333373F3F77F3333333330900907
      3333333337F77F77F33333333003709073333333377377F77F33333337333709
      073333333733377F77F33333333333709033333333333377F7F3333333333337
      0733333333333337773333333333333333333333333333333333}
    NumGlyphs = 2
  end
  object EdtKey: TEdit
    Left = 16
    Top = 32
    Width = 265
    Height = 21
    TabOrder = 5
    Text = ''
  end
  object EdtCypher64: TEdit
    Left = 16
    Top = 205
    Width = 505
    Height = 21
    TabOrder = 6
  end
  object EdtIV: TEdit
    Left = 16
    Top = 75
    Width = 265
    Height = 21
    TabOrder = 7
    Text = ''
  end
  object EdtCypherHex: TEdit
    Left = 17
    Top = 246
    Width = 505
    Height = 21
    TabOrder = 8
  end
  object BtnKAT: TButton
    Left = 301
    Top = 47
    Width = 201
    Height = 25
    Caption = 'Known Answer Test (KAT) Vectors'
    TabOrder = 9
    OnClick = BtnKATClick
  end
  object BtnHexConvert: TButton
    Left = 301
    Top = 80
    Width = 75
    Height = 20
    Caption = 'Hex conversie'
    TabOrder = 10
    OnClick = BtnHexConvertClick
  end
  object DCP_rijndael1: TDCP_rijndael
    Id = 9
    Algorithm = 'Rijndael'
    MaxKeySize = 256
    BlockSize = 128
    Left = 432
    Top = 80
  end
end

========== uRijndael.pas ==============

unit uRijndael;
// Helper functions for 256-bit Rijndael/AES encryption with DCPcrypt

interface

Uses
  StdCtrls;

function RijndaelEncryptHex(hexstrKey,hexstrIV,hexstrPlain: String; MMo: TMemo = nil): String;
function RijndaelDecryptHex(hexstrKey,hexstrIV,hexstrCypher: String; MMo: TMemo = nil): String;
// Input en output zijn strings met hex waarden ('014730f80ac625fe84f026c60bfd547d')
//
// Deze routines gebruiken een 256-key AES/Rijndael encryptie, waarbij de plaintext
// met NULL waarden ge-pad wordt tot een veelvoud van de blocksize.
// Merk op dat de initializatievector even groot moet zijn als de blocksize (128 bits, dus een hex string van 32 tekens).
//
// Als TMemo gespecificeerd is wordt daar naar toe gelogd.

// Helper routines:
function HexToString(H: String): String;
function StringtoHex(Data: string; WithSpaces: Boolean = false): string;
function HexToInt(HexNum: string): LongInt;

implementation

Uses
  SysUtils,
  DCPbase64, DCPcrypt2, DCPblockciphers, DCPrijndael;

type
  KeyBuffer  = Array[1..32] of Byte;
  IVBuffer   = Array[1..16] of Byte;

function HexToString(H: String): String;
var I : Integer;
begin
  Result:= '';
  for I := 1 to length (H) div 2 do
    Result:= Result+Char(StrToInt('$'+Copy(H,(I-1)*2+1,2)));
end;

function StringtoHex(Data: string; WithSpaces: Boolean = false): string;
var
  i, i2: Integer;
  s: string;
begin
  i2 := 1;
  for i := 1 to Length(Data) do
  begin
    Inc(i2);
    if i2 = 2 then
    begin
      if WithSpaces then s  := s + ' ';
      i2 := 1;
    end;
    s := s + IntToHex(Ord(Data[i]), 2);
  end;
  Result := s;
end;

function HexToInt(HexNum: string): LongInt;
begin
   Result := StrToInt('$' + HexNum) ;
end;

function FilterHex(S: String): String;
// Filters all hex characters 0..F (case insensitive) uit S
var
   SOut: String;
   l   : Word;
begin
   SOut := '';
   for l := 1 to Length(S) do
      if not (S[l] in ['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','A','B','C','D','E','F']) then
         SOut := SOut + S[l];
   Result := SOut;
end;

function RijndaelEncryptHex(hexstrKey,hexstrIV,hexstrPlain: String; MMo: TMemo = nil): String;
var
  InBuf,OutBuf  : array of byte;
  BufSizeInBytes: Word;
  KeyBuf        : KeyBuffer;
  IVBuf         : IVBuffer;
  l,i           : Integer;
  Bytes,SOut    : String;
  DCPR          : TDCP_rijndael;
begin
  l := Length(HexStrKey);
  Assert(l=64,'Key heeft ongeldige lengte (moet 64 chars zijn): ' + IntToStr(l));
  Assert(FilterHex(HexStrKey) = '','Key heeft ongeldige tekens: ' + HexStrKey);
  l := Length(HexStrIV);
  Assert(l=32,'IV heeft ongeldige lengte (moet 32 chars zijn): ' + IntToStr(l));
  Assert(FilterHex(HexStrIV) = '','IV heeft ongeldige tekens: ' + HexStrIV);
  Assert(FilterHex(hexstrPlain) = '','Plaintext heeft ongeldige tekens: ' + hexstrPlain);
  l := Length(hexstrPlain);
  Assert(l MOD 2 = 0,'Plaintext heeft oneven lengte: ' + hexstrPlain);
  if Mmo<> nil then begin
    Mmo.Lines.Add('Key: ' + hexstrKey);
    Mmo.Lines.Add('IV: ' + hexstrIV);
    Mmo.Lines.Add('Plaintext: ' + hexstrPlain);
    end;
  l := Length(hexstrKey) DIV 2;
  for i := 1 to l do KeyBuf[i] := HexToInt(Copy(hexstrKey,2*(i-1)+1,2));
  l := Length(hexstrIV) DIV 2;
  for i := 1 to l do IVBuf[i] := HexToInt(Copy(hexstrIV,2*(i-1)+1,2));
  // Pad with zeroes:
  while Length(hexstrPlain) MOD 32 <> 0 do hexstrPlain := hexstrPlain + '00';
  BufSizeInBytes := Length(hexstrPlain) DIV 2;
  SetLength(InBuf,BufSizeInBytes);
  SetLength(OutBuf,BufSizeInBytes);
  for i := 0 to BufSizeInBytes-1 do InBuf[i] := HexToInt(Copy(hexstrPlain,2*i+1,2));
  DCPR := TDCP_rijndael.Create(nil);
  DCPR.Init(KeyBuf,256,@IVBuf);
  DCPR.EncryptCBC(InBuf[0],OutBuf[0],BufSizeInBytes);
  DCPR.Burn; // Leeg memory buffers voor security
  DCPR.Free;
  SOut := '';
  for i := 0 to BufSizeInBytes-1 do begin SOut := SOut + Chr(OutBuf[i]); Bytes := Bytes + IntToStr(OutBuf[i]) + ' '; end;
  if Mmo<> nil then begin
    Mmo.Lines.Add('Cyphertext (bytes): ' + Bytes);
    Mmo.Lines.Add('Cyphertext (base64): ' + Base64EncodeStr(SOut));
    end;
  SOut := LowerCase(StringToHex(SOut));
  if Mmo<> nil then begin
    Mmo.Lines.Add('Cyphertext (hex): ' + SOut);
    Mmo.Lines.Add('');
    end;
  Result := SOut;
end; { RijndaelEncryptHex }


function RijndaelDecryptHex(hexstrKey,hexstrIV,hexstrCypher: String; MMo: TMemo = nil): String;
var
  InBuf,
  OutBuf: array of byte;
  BufSizeInBytes : Word;
  KeyBuf: KeyBuffer;
  IVBuf : IVBuffer;
  l,i   : Integer;
  SOut  : String;
  DCPR  : TDCP_rijndael;
begin
  l := Length(HexStrKey);
  Assert(l=64,'Key heeft ongeldige lengte (moet 64 chars zijn): ' + IntToStr(l));
  Assert(FilterHex(HexStrKey) = '','Key heeft ongeldige tekens: ' + HexStrKey);
  l := Length(HexStrIV);
  Assert(l=32,'IV heeft ongeldige lengte (moet 32 chars zijn): ' + IntToStr(l));
  Assert(FilterHex(HexStrIV) = '','IV heeft ongeldige tekens: ' + HexStrIV);
  Assert(FilterHex(hexstrCypher) = '','Cyphertext heeft ongeldige tekens: ' + hexstrCypher);
  l := Length(hexstrCypher);
  Assert(l MOD 2 = 0,'Cyphertext heeft oneven lengte: ' + hexstrCypher);
  if Mmo<> nil then begin
    Mmo.Lines.Add('Key: ' + hexstrKey);
    Mmo.Lines.Add('IV: ' + hexstrIV);
    Mmo.Lines.Add('CypherText: ' + hexstrCypher);
    end;
  l := Length(hexstrKey) DIV 2;
  for i := 1 to l do KeyBuf[i] := HexToInt(Copy(hexstrKey,2*(i-1)+1,2));
  l := Length(hexstrIV) DIV 2;
  for i := 1 to l do IVBuf[i] := HexToInt(Copy(hexstrIV,2*(i-1)+1,2));
  // Pad with zeroes:
  BufSizeInBytes := Length(hexstrCypher) DIV 2;
  SetLength(InBuf,BufSizeInBytes);
  SetLength(OutBuf,BufSizeInBytes);
  for i := 0 to BufSizeInBytes-1 do InBuf[i] := HexToInt(Copy(hexstrCypher,2*i+1,2));
  DCPR := TDCP_rijndael.Create(nil);
  DCPR.Init(KeyBuf,256,@IVBuf);
  DCPR.DecryptCBC(InBuf[0],OutBuf[0],BufSizeInBytes);
  DCPR.Burn;
  DCPR.Free;
  SOut := '';
  for i := 0 to BufSizeInBytes-1 do SOut := SOut + Chr(OutBuf[i]);
  SOut := LowerCase(StringToHex(SOut));
  if Mmo<> nil then begin
    Mmo.Lines.Add('Plaintext (hex): ' + SOut);
    Mmo.Lines.Add('');
  end;
  Result := SOut;
end; { RijndaelDecryptHex }

end.
于 2012-07-30T12:08:10.123 回答
0

1) 为 Delphi 和 C# 尝试其他 AES128 实现。例如 Delphi 的 LockBox 3。也为 dot-net 寻找其他东西。这将让您检查您的环境中是否有一些库被破坏。

2) 如果 Delphi 的所有库在它们之间是一致的,并且 C# 的所有库在它们之间是一致的,但是这些集群具有不同的结果,那么你知道你对于那个字符串有不同的 BINARY 数据。

不同的 Delphi 版本具有不同的字符串表示形式,没有指定 Delphi 版本(SO 上有 Delphi 特定版本的标签)并显示 vars 的类型声明,您几乎无法在字符串后面显示二进制数据。

Java 在早期版本中将 UCS-2 用于字符串,现在它使用 UTF-16。

不知道点网。

但是 - 你必须做实验并将字符串跟踪到原始字节数组。然后确保这些数组完全匹配。这将带您了解字符串实现或始终将字符串转换为字节并返回到您的自定义桥接例程中,您始终可以完全控制。

而且 - 毕竟 - 你最好对此进行广泛的单元测试。因此,如果以后对库、语言或编译器设置进行任何更改后会影响 cypering - 您会立即知道。一个月前,我对 Spring4D 散列函数进行了 Win64 asm 优化,但对加密一无所知 - 多亏了这些单元测试 :-)

于 2012-07-30T08:35:17.863 回答
0

加密中有许多参数,例如:

密钥长度、编码模式、oaep、charset 等等所以在双方都使用一个组件是合理的,chilkat 比其他组件更完整。所以如果可能的话,你可以在两边都使用它。

于 2021-08-22T12:55:12.877 回答