Delphi Turbopower Lockbox3-我可以控制AES-256加密的初始化向量和填充吗?请求同等加密

Delphi Turbopower Lockbox3-我可以控制AES-256加密的初始化向量和填充吗?请求同等加密,delphi,encryption,aes,lockbox-3,Delphi,Encryption,Aes,Lockbox 3,下面给出的代码是否有等效的加密程序。 当前实现不支持加密,并引发“功能不受支持”异常 下面的例程成功地将此密码“G6DR0607ZXRu24envBxPRA==”解密为其纯文本值“1”。我需要反转这个过程,得到相同的给定密码 我希望有人能帮助我提供一个工作等效代码来加密纯文本值,使用解密例程中的相同过程 const Key: array of byte = [$61,$A6,$02,$D1,$E6,$89,$87,$A3,$7C,$0B,$54,$D2,$64,$7D,

下面给出的代码是否有等效的加密程序。 当前实现不支持加密,并引发“功能不受支持”异常

下面的例程成功地将此密码“G6DR0607ZXRu24envBxPRA==”解密为其纯文本值“1”。我需要反转这个过程,得到相同的给定密码

我希望有人能帮助我提供一个工作等效代码来加密纯文本值,使用解密例程中的相同过程

const
  Key: array of byte = [$61,$A6,$02,$D1,$E6,$89,$87,$A3,$7C,$0B,$54,$D2,$64,$7D,
                        $B9,$41,$D0,$E6,$56,$DE,$CF,$A2,$5B,$6C,$76,$4A,$BB,$FA,
                        $DB,$CD,$41,$2D];
  IV: array of byte  = [$86,$78,$1C,$D2,$66,$91,$F7,$91,$3B,$2A,$44,$10,$DF,$38,
                        $E4,$47];

function DecryptAES256(const Value: String): String;
var
  Codec: TCodec;
  CryptographicLibrary: TCryptographicLibrary;
  CipherStream, PlainTextStream: TStream;
  buffer: array of Byte;
begin
  Codec                          := TCodec.Create( nil);
  CryptographicLibrary           := TCryptographicLibrary.Create( nil);

  CipherStream                   := TMemoryStream.Create;
  PlainTextStream                := TMemoryStream.Create;

  try
    Codec.CryptoLibrary          := CryptographicLibrary;
    CryptographicLibrary.RegisterStreamCipher(StreamToBlock_Adapter_CSharpVariant);
    Codec.StreamCipherId         := 'CSharp.StreamToBlock';
    Codec.BlockCipherId          := Format( AES_ProgId, [256]);
    Codec.AsymetricKeySizeInBits := 256;
    Codec.Cipher                 := '[AES-256*]';
    Codec.ChainModeId            := CBC_ProgId;

    CipherStream.WriteBuffer( Key[0], Length(Key));
    CipherStream.Position        := 0;
    Codec.InitFromStream(CipherStream);
    CipherStream.Size            := 0;
    CipherStream.WriteBuffer( IV[0], Length(IV));
    Base64_to_stream(Value, CipherStream);
    CipherStream.Position        := 0;
    Codec.DecryptStream(PlainTextStream, CipherStream);
    PlainTextStream.Position     := 0;
    SetLength(buffer, PlainTextStream.Size);
    PlainTextStream.ReadBuffer(buffer[0], Length(buffer));
    Result                       := StripNonAscii(ByteToString(buffer));
  finally
    CipherStream.Free;
    PlainTextStream.Free;
    Codec.Free;
    CryptographicLibrary.Free;
  end;
end;

下面是一个示例程序,用于加密/解密AES-256中的UTF-16LE字符串,修改填充以与填充的C#stype互操作。锁盒3并不是为非正统的填充技术而设计的,比如C#uses,但是通过一些工作,我们可以适应

  • 编译器=Delphi XE6
  • TPLB3版本=
  • 目标平台=Win32
  • Config=DEBUG
  • 应用程序类型=VCL表单
清单1:程序CSharp2.dpr 清单2:umfmCSharp2Demo.pas
什么相关职位?这是web,旋转一个线程。我假设相关的帖子是:这里有一个明显的错误:Codec.Cipher属性是一个只在设计时使用的伪属性。经过一些小的调整,我已经能够在Delphi 2010中测试这段代码-它工作得非常好。但是流操作呢,我的意思是从磁盘加载文件并保存到磁盘上?你能举一些例子吗?
program CSharp2;

uses
  Vcl.Forms,
  umfmCSharp2Demo in 'umfmCSharp2Demo.pas' {mfmCSharp2Demo};

{$R *.res}

begin
  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  Application.CreateForm(TmfmCSharp2Demo, mfmCSharp2Demo);
  Application.Run;
end.
unit umfmCSharp2Demo;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, System.Actions,
  Vcl.ActnList, Vcl.PlatformDefaultStyleActnCtrls, Vcl.ActnMan, Vcl.ExtCtrls,
  TPLB3.Codec, TPLB3.CryptographicLibrary;

type
  TmfmCSharp2Demo = class(TForm)
    edtKey: TLabeledEdit;
    edtIV: TLabeledEdit;
    rdChain: TRadioGroup;
    memoPlaintext: TMemo;
    lblPlaintext: TLabel;
    edtCiphertext: TLabeledEdit;
    actmngrMainActions: TActionManager;
    Button1: TButton;
    Button2: TButton;
    memoResults: TMemo;
    actEncrypt: TAction;
    actDecrypt: TAction;
    procedure actEncryptExecute(Sender: TObject);
    procedure actDecryptExecute(Sender: TObject);

  private
    procedure Put( const Line: string; const Args: array of const);
    procedure Setup( var Codec: TCodec; var CryptographicLibrary: TCryptographicLibrary);
    procedure SetIV( var Codec: TCodec; var Padder: TObject);
  end;

var
  mfmCSharp2Demo: TmfmCSharp2Demo;

implementation














uses TPLB3.Constants,
     TPLB3.StreamUtils, TPLB3.StreamToBlock;

{$R *.dfm}


type
  TCSharpPadder = class( TObject)
    private
      FIV: TBytes;
    public
      constructor Create( const AIV: TBytes);
      procedure SetIV_For_Decrypt( Value: TMemoryStream);
    end;



function StripSpace( const Spacey: string): string;
var
  Builder: TStringBuilder;
  i: integer;
begin
Builder := TStringBuilder.Create;
Builder.Append( Spacey);
for i := Builder.Length - 1 downto 0 do
  if CharInSet( Builder.Chars[ i], [' ', #9, #$A, #$D]) then
    Builder.Remove( i, 1);
result := Builder.ToString;
Builder.Free
end;

procedure TmfmCSharp2Demo.Setup(
  var Codec: TCodec;
  var CryptographicLibrary: TCryptographicLibrary);
begin
Codec := TCodec.Create( nil);
CryptographicLibrary := TCryptographicLibrary.Create( nil);
Codec.CryptoLibrary  := CryptographicLibrary;
Codec.StreamCipherId := BlockCipher_ProgId;
Codec.BlockCipherId  := Format( AES_ProgId, [256]);
case rdChain.ItemIndex of
  0:  Codec.ChainModeId := CBC_ProgId;
  1:  Codec.ChainModeId := CFB_ProgId;
  2:  Codec.ChainModeId := CFB8bit_ProgId;
  3:  Codec.ChainModeId := CTR_ProgId;
  4:  Codec.ChainModeId := OFB_ProgId;
  end
end;


procedure TmfmCSharp2Demo.SetIV( var Codec: TCodec; var Padder: TObject);
var
  IV_AsStream: TStream;
  IV: TBytes;
  CSharpPadder: TCSharpPadder;
begin
Padder := nil;
IV_AsStream := TMemoryStream.Create;
try
  Base64_to_stream( StripSpace( edtIV.Text), IV_AsStream);
  IV_AsStream.Position := 0;
  SetLength( IV, IV_AsStream.Size);
  IV_AsStream.ReadData( IV, Length( IV))
finally
  IV_AsStream.Free
  end;
if Length( IV) <> 16 then
  raise Exception.Create( 'To encrypt C# style, you must supply a 16 byte IV.');
CSharpPadder  := TCSharpPadder.Create( IV);
Padder        := CSharpPadder;
Codec.OnSetIV := CSharpPadder.SetIV_For_Decrypt
end;

procedure TmfmCSharp2Demo.actEncryptExecute( Sender: TObject);
var
  Key: TStream;
  Codec: TCodec;
  CryptographicLibrary: TCryptographicLibrary;
  s: string;
  Builder: TStringBuilder;
  BlockLenInUnits, PadIdx: integer;
  Ciphertext: TStream;
  Padder: TObject;
  Temp: TBytes;
  Len: integer;
begin
try
  // 1. Create the components dynamically.
  //  An alternative would be to use design-time properties.
  Setup( Codec, CryptographicLibrary);
  Ciphertext := TMemoryStream.Create;
  try

    // 2. Pad the plaintext, C# style.
    //  This is an inferior style of padding. Only do it if you need
    //  interoperability with C# libraries.
    Builder := TStringBuilder.Create;
    Builder.Append( memoPlaintext.Lines.Text);
    BlockLenInUnits := 16 div SizeOf( Char);
    for PadIdx := 1 to (BlockLenInUnits - (Builder.Length mod BlockLenInUnits)) mod BlockLenInUnits do
      // C# just pads out with zeros.
      Builder.Append( Char( #0));
    s := Builder.ToString;
    Builder.Free;

    // 3. Read in the IV.
    //  Normally IV is set automatically by TP Lockbox 3, but C# library is pretty stupid
    //  and requires manual management.
    SetIV( Codec, Padder);

    try
      // 4. Read in the binary key (instead of setting a string password),
      //  and initialize the Codec.
      Key := TMemoryStream.Create;
      try
        Base64_to_stream( StripSpace( edtKey.Text), Key);
        Key.Position := 0;
        Codec.InitFromStream( Key);
      finally
        Key.Free
        end;

      // 5. Encrypt using a UTF-16LE format.
      Codec.Begin_EncryptMemory( Ciphertext);
      if s.Length > 0 then
        Codec.EncryptMemory( s[ Low( s)], s.Length * SizeOf( Char));
      Codec.End_EncryptMemory;
    finally
      Padder.Free
      end;

    // 8. TP LockBox 3 automatically seeds (prepend) the cipher stream with
    //  the low 8 bytes of the IV. But we don't need this for C# interoperability,
    //  so remove these bytes from the stream.
    if CipherText.Size <> 0 then
      begin
      Ciphertext.Position := 8;
      Len := CipherText.Size - CipherText.Position;
      SetLength( Temp, Len);
      if Len > 0 then
        CipherText.ReadData( Temp, Len);
      CipherText.Size := Len;
      CipherText.Position := 0;
      CipherText.WriteData( Temp, Len)
      end;
    edtCiphertext.Text := Stream_to_Base64( Ciphertext);

  // 9. Tidy up
  finally
    Ciphertext.Free;
    Codec.Free;
    CryptographicLibrary.Free;
    end;
  Put( 'Encryption done.', [])
except on E: Exception do
    begin
    Put( 'Encryption failed: %s: %s', [E.ClassName, E.Message]);
    end
  end;
end;

procedure TmfmCSharp2Demo.actDecryptExecute( Sender: TObject);
var
  Key: TStream;
  Codec: TCodec;
  CryptographicLibrary: TCryptographicLibrary;
  Plaintext: TStream;
  Padder: TObject;
  Temp: TBytes;
  Len: integer;
  CipherStream: TMemoryStream;
  idx, Count: Integer;
begin
try
  // 1. Setup
  Setup( Codec, CryptographicLibrary);
  Plaintext := TMemoryStream.Create;
  try

    // 2. Read in the IV.
    //  Normally IV is set automatically by TP Lockbox 3, but C# library is pretty stupid
    //  and requires manual management.
    SetIV( Codec, Padder);
    CipherStream := TMemoryStream.Create;
    try
      // 3. Read in the binary key (instead of setting a string password),
      //  and initialize the Codec.
      Key := TMemoryStream.Create;
      try
        Base64_to_stream( StripSpace( edtKey.Text), Key);
        Key.Position := 0;
        Codec.InitFromStream( Key);
      finally
        Key.Free
        end;

      // 3. Fake a prepended IV. This value doesn't matter any way.
      //     It gets overwritten by the Padder object.
      Temp := TBytes.Create( 0, 0, 0, 0, 0, 0, 0, 0);
      CipherStream.WriteData( Temp, 8);

      // 4. Decrypt using a UTF-16LE format.
      Codec.Begin_DecryptMemory( Plaintext);
      Base64_to_stream( StripSpace( edtCiphertext.Text), CipherStream);
      Codec.DecryptMemory( CipherStream.Memory^, CipherStream.Size);
      Codec.End_DecryptMemory;
    finally
      Padder.Free;
      CipherStream.Free
      end;

    // 5. Strip C# style padding.
    Plaintext.Position := 0;
    SetLength( Temp, Plaintext.Size);
    Plaintext.ReadData( Temp, Length( Temp));
    Count := 0;
    Len := Length( Temp);
    if Len >= 2 then
      for idx := (Len div 2) - 1 downto 0 do
        begin // Detect how many padding zeroes.
        if (Temp[idx*2] = 0) and (Temp[idx*2 + 1] = 0) then continue;
        Count := (idx + 1) * 2;
        break
        end;
    memoPlaintext.Text := TEncoding.Unicode.GetString( Temp, 0, Count);

  // 9. Tidy up
  finally
    Plaintext.Free;
    Codec.Free;
    CryptographicLibrary.Free;
    end;
  Put( 'Decryption done.', [])
except on E: Exception do
    begin
    Put( 'Decryption failed: %s: %s', [E.ClassName, E.Message]);
    end
  end;
end;


procedure TmfmCSharp2Demo.Put( const Line: string; const Args: array of const);
var
  sLine: string;
begin
sLine := Line;
if Length( Args) > 0 then
  sLine := Format( sLine, Args);
memoResults.Lines.Add( sLine)
end;

constructor TCSharpPadder.Create( const AIV: TBytes);
begin
FIV := AIV
end;

procedure TCSharpPadder.SetIV_For_Decrypt( Value: TMemoryStream);
begin
Value.Size := Length( FIV);
Value.Position := 0;
Value.WriteData( FIV, Length( FIV))
end;

end.
object mfmCSharp2Demo: TmfmCSharp2Demo
  Left = 0
  Top = 0
  Caption = 'C# Demo 2'
  ClientHeight = 424
  ClientWidth = 554
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  DesignSize = (
    554
    424)
  PixelsPerInch = 96
  TextHeight = 13
  object lblPlaintext: TLabel
    Left = 210
    Top = 96
    Width = 289
    Height = 13
    Caption = 'Plaintext datum (encoded as UTF-16LE; CR.LF line endings):'
    FocusControl = memoPlaintext
  end
  object edtKey: TLabeledEdit
    Left = 8
    Top = 24
    Width = 538
    Height = 24
    Anchors = [akLeft, akTop, akRight]
    EditLabel.Width = 171
    EditLabel.Height = 13
    EditLabel.Caption = 'Key (32 bytes encoded as base64):'
    Font.Charset = DEFAULT_CHARSET
    Font.Color = clWindowText
    Font.Height = -13
    Font.Name = 'Courier New'
    Font.Style = []
    ParentFont = False
    TabOrder = 0
    Text = '0f2EYYpNRTE16ve7dYxbvGuk+BHR/YRhik1FMTXq97s='
  end
  object edtIV: TLabeledEdit
    Left = 8
    Top = 72
    Width = 538
    Height = 24
    Anchors = [akLeft, akTop, akRight]
    EditLabel.Width = 261
    EditLabel.Height = 13
    EditLabel.Caption = 'Initialization Vector (IV; 16 bytes encoded as base64):'
    Font.Charset = DEFAULT_CHARSET
    Font.Color = clWindowText
    Font.Height = -13
    Font.Name = 'Courier New'
    Font.Style = []
    ParentFont = False
    TabOrder = 1
    Text = 'kHLzYvYBxooAAAAAAAAAAA=='
  end
  object rdChain: TRadioGroup
    Left = 8
    Top = 99
    Width = 185
    Height = 102
    Caption = 'Chaining mode'
    Columns = 2
    ItemIndex = 0
    Items.Strings = (
      'CBC'
      'CFB'
      'CFB - 8 bit'
      'CTR'
      'OFB')
    TabOrder = 2
  end
  object memoPlaintext: TMemo
    Left = 208
    Top = 112
    Width = 338
    Height = 89
    Anchors = [akLeft, akTop, akRight]
    ScrollBars = ssVertical
    TabOrder = 3
  end
  object edtCiphertext: TLabeledEdit
    Left = 8
    Top = 224
    Width = 538
    Height = 21
    Anchors = [akLeft, akTop, akRight]
    EditLabel.Width = 399
    EditLabel.Height = 13
    EditLabel.Caption = 
      'Ciphertext datum (encoded as base64; byte count must be a whole ' +
      'multiple of 16):'
    TabOrder = 4
  end
  object Button1: TButton
    Left = 8
    Top = 251
    Width = 273
    Height = 25
    Action = actEncrypt
    TabOrder = 5
  end
  object Button2: TButton
    Left = 287
    Top = 251
    Width = 259
    Height = 25
    Action = actDecrypt
    TabOrder = 6
  end
  object memoResults: TMemo
    Left = 8
    Top = 282
    Width = 538
    Height = 134
    Anchors = [akLeft, akTop, akRight, akBottom]
    Color = clInfoBk
    ReadOnly = True
    ScrollBars = ssVertical
    TabOrder = 7
  end
  object actmngrMainActions: TActionManager
    Left = 256
    Top = 144
    StyleName = 'Platform Default'
    object actEncrypt: TAction
      Caption = 'Encrypt by AES-256 using C# style padding'
      OnExecute = actEncryptExecute
    end
    object actDecrypt: TAction
      Caption = 'Decrypt by AES-256 using C# style padding'
      OnExecute = actDecryptExecute
    end
  end
end