了解使用LockBox 3和Delphi XE2加密文件

时间:2013-02-04 22:26:55

标签: file encryption delphi-xe2 lockbox-3

所以我当前的任务涉及获取给定的文本字符串(例如:ABC123)并使用LockBox3的EncryptString(源,目标)函数对其进行加密。我可以成功加密字符串并获取输出以保存到.txt文件。

此过程的下一步是使用LockBox3的EncryptFile(源,目标)函数获取包含我已加密字符串的.txt,并使用AES-128加密所述文件(与字符串加密相同)但使用diff密码)

基本上,我可以让字符串正确加密并输出到.txt文件。然后我请求用户抓住.txt,并将其带入我的程序。然后程序尝试获取该文件并进一步加密。当我这样做时,我得到一个文件输出..但是当我去解密所述文件时,生成的.txt不包含原始文本..或任何文本。我基本上对如何加密.txt文件感到困惑。有什么建议?如果这个问题/代码不够具体,我道歉。请让我知道还有什么,如果有什么我需要澄清的情况,以便更好地帮助你们了解我正在努力的事情!谢谢!

EDIT1:

大家好,谢谢你的建议。澄清:

我在解密过程中使用的流将在以后使用,因此在我解密文件后,我可以从中读取并解密剩余的加密(从第一步)字符串。

进一步澄清:

用于加密字符串的我的编解码器(Codec1)使用带有CBC的AES-128,标签为" 0"和AsymetricKeySize为1024(我非常确定这种加密方式无关紧要吗?)我的加密文件编解码器(上面的Codec2)具有相同的设置,但Codec1和Codec2的密码不同。基本上,我使用Codec1加密字符串并将其写入.txt,然后我使用Codec2加密所述文件..最终解密它并使用Stream从所述文件读取并再次使用Codec1解密该字符串。

我的文件加密/解密代码:

字符串加密:

procedure TForm1.Button1Click(Sender: TObject);
begin
  codec1.Password := WORD_1;
  //Begin encryption
  sPlainText := Serial_number.Number;         //Store Serial Number of machine 
  codec1.EncryptString(sPlainText,CipherText);   //Encrypt (base64)
  listbox2.Clear;
  listbox2.AddItem(Ciphertext, AnsiCipher);
  end;

将加密的字符串写入文件并保存:

saveDialog := TSaveDialog.Create(self);
  saveDialog.Title := 'Choose location to save Authentication Code';
  saveDialog.InitialDir := 'C:\';
  saveDialog.DefaultExt := '';
  saveDialog.FilterIndex := 1;
  saveDialog.Execute();
  glb_fileName1 := saveDialog.FileName;
 //open stream and write cipher to a .txt of chosen location
  try
    Stream := TFileStream.Create(saveDialog.GetNamePath + saveDialog.FileName + '.txt', fmOpenReadWrite);
  except
    Stream := TFileStream.Create(saveDialog.GetNamePath + saveDialog.FileName + '.txt', fmCreate);
  end;
    for k := 1 to (Length(CipherText)) do
        buff[k] := byte(CipherText[k]);
    ptr := @buff[1];
    Stream.WriteBuffer(ptr^, Length(CipherText));
  Stream.Free;
  saveDialog.Free;

获取文件加密的.txt位置

procedure TForm1.Button4Click(Sender: TObject);
var
  fileName : string;
  holder_obj : TSerial_number;
begin
  holder_obj := Tserial_number.Create;
  listbox4.Clear;

if OpenTextFileDialog1.Execute() then
   fileName := OpenTextFileDialog1.FileName;     
   listbox4.AddItem(filename, holder_obj);
end;

文件加密:

  Codec2.Password := WORD_2;
  sCrypt := glb_fileName1 + '_enc.txt';
  Codec2.EncryptFile(glb_fileName1+'.txt', sCrypt);

抓取加密文件进行解密:

procedure TForm1.Button3Click(Sender: TObject);
var
  holder_obj : TSerial_number;
begin
  holder_obj := Tserial_number.Create;
  listbox3.Clear;
if OpenTextFileDialog1.Execute() then
   glb_fileName2 := OpenTextFileDialog1.FileName;
   listbox3.AddItem(glb_filename2, holder_obj);
end;

文件解密(打开一个流,一旦我拥有它就从解密文件中读取,以便我可以解密它包含的加密字符串):

procedure TForm1.Button5Click(Sender: TObject);
var
  saveDialog : TSaveDialog;
begin
  saveDialog := TSaveDialog.Create(self);
  saveDialog.Title := 'Choose location to save Decrypted Authentication Code';
  saveDialog.InitialDir := 'C:\';
  saveDialog.DefaultExt := '';
  saveDialog.Execute();
  glb_fileName1:= saveDialog.FileName;
 //open stream and write cipher to a .txt of chosen location
  try
    Stream := TFileStream.Create(saveDialog.GetNamePath + saveDialog.FileName + '.txt', fmOpenReadWrite);
  except
    Stream := TFileStream.Create(saveDialog.GetNamePath + saveDialog.FileName + '.txt', fmCreate);
  end;
  Stream.Free;

  Codec2.Password := WORD_2;
  Codec2.DecryptFile(glb_fileName2, saveDialog.FileName + '.txt');
  saveDialog.Free;
end;

2 个答案:

答案 0 :(得分:2)

您提供的代码是复杂的尝试,看看出了什么问题。如果您只是想看看编码/解码是否有效,您应该只需要像下面的代码那样的简单代码。只需将测试文件放在驱动器上并对名称进行硬编码即可。这将告诉您,如果InputFile.txt和Un-EncryptedFile.text相同,编码/解码将起作用。

一旦完成工作,您就可以开始构建完整的例程。您发布的代码实际上与按钮点击之间使用的全局变量混淆,只是命名为1,2等。您创建的流不会做任何事情,只会更多地混淆问题。剥离基础知识并首先使其工作。

procedure TestEncodeDecode();
begin
  Codec2.Password := WORD_2;
  Codec2.EncryptFile('c:\InputFile.txt', 'c:\EncryptedFile.txt');
  Codec2.DecryptFile('c:\EncryptedFile.txt', 'c:\Un-EncryptedFile.txt');
end;

答案 1 :(得分:2)

我对你提出的问题感到困惑。冒着误解你的问题的风险,我假设你在尝试:

  1. 加密字符串;
  2. 将加密的字符串存储在文件中
  3. 加密文件(双重加密)
  4. 反转前面的步骤以重建原始字符串。
  5. selftest()方法证明了这一点。

    如果这种解释是正确的,请考虑以下解决方案。 (在Delphi 2010中测试过。不在XE2中测试)

    unit uDoubleEncrypt;
    
    interface
    
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, uTPLb_CryptographicLibrary, uTPLb_BaseNonVisualComponent,
      uTPLb_Codec;
    
    type
      TmfmDoubleEncrypt = class(TForm)
        Codec1: TCodec;
        Codec2: TCodec;
        CryptographicLibrary1: TCryptographicLibrary;
        btnGo: TButton;
        memoLog: TMemo;
        dlgSave1: TSaveDialog;
        dlgOpen1: TOpenDialog;
        procedure btnGoClick(Sender: TObject);
    
      private
        FFileName_Plain, FFileName_Cipher: string;
        sSerial: string;
        function  EncryptStringWithCodec1( const sPlaintext: string): ansistring;
        function  GetFileName( dlgOpenX: TOpenDialog; var sFN: string): boolean;
        procedure SaveAnsiStringToFile( const sFN: string; const sSerialCipherText: AnsiString);
        function  ReconstructSerial: string;
    
      public
        procedure Put( const LineFmt: string; const Args: array of const);
        procedure Button1Click;
        procedure Button4Click;
        function  SelfTest: boolean;
      end;
    
    var
      mfmDoubleEncrypt: TmfmDoubleEncrypt;
    
    implementation
    
    {$R *.dfm}
    
    procedure TmfmDoubleEncrypt.btnGoClick( Sender: TObject);
    var
      WORD_1, WORD_2: string;
    begin
    WORD_1 := 'red';
    WORD_2 := 'blue';
    sSerial := '123'; // Serial_number.Number; // Store Serial Number of machine
    Codec1.Password := WORD_1;
    Codec2.Password := WORD_2;
    
    // Run the self test.
    SelfTest;
    
    // Clean up.
    Codec1.Burn;
    Codec2.Burn
    // You may also want to delete temporary files here.
    end;
    
    function TmfmDoubleEncrypt.EncryptStringWithCodec1(
      const sPlaintext: string): ansistring;
    begin
    // Assume Codec1 properties already set-up:
    //  1. Password
    //  2. CryptoLibrary
    //  3. Cipher (at design-time)
    //  4. Chain-mode
    Codec1.Reset; // Normally not necessary. A defence agains the codec being left in a corrupt state.
    Codec1.EncryptString( sPlaintext, result)
    end;
    
    
    function TmfmDoubleEncrypt.GetFileName(
      dlgOpenX: TOpenDialog; var sFN: string): boolean;
    begin
    result := dlgOpenX.Execute;
    if result then
      sFN := dlgOpenX.FileName
    end;
    
    procedure TmfmDoubleEncrypt.Put(
      const LineFmt: string; const Args: array of const);
    begin
    memoLog.Lines.Add( Format( LineFmt, Args))
    end;
    
    procedure TmfmDoubleEncrypt.SaveAnsiStringToFile(
      const sFN: string; const sSerialCipherText: AnsiString);
    const
      Modes: array[boolean] of word = (fmCreate, fmOpenReadWrite);
    var
      SaveStream: TStream;
    begin
    SaveStream := TFileStream.Create( sFN, Modes[ FileExists( sFN)]);
    try
      SaveStream.Size := 0;
      if sSerialCipherText <> '' then
        SaveStream.WriteBuffer( sSerialCipherText[1], Length( sSerialCipherText))
    finally
      SaveStream.Free
      end
    end;
    
    procedure TmfmDoubleEncrypt.Button1Click;
    // This method is equivalent to gEdit101's Button1Click()
    var
      sPlainText: string;
      sSerialCipherText: AnsiString;
      sFN: string;
    begin
    sPlainText := sSerial;
    sSerialCipherText := EncryptStringWithCodec1( sPlainText);
    Put( 'Encrypted serial number is %s', [sSerialCipherText]);
    if GetFileName( dlgOpen1, sFN) then
      begin
      SaveAnsiStringToFile( sFN, sSerialCipherText);
      FFileName_Plain := sFN; // Store for Button4Click()
      Put('encrypted serial number save to file "%s".',[sFN])
      end;
    end;
    
    procedure TmfmDoubleEncrypt.Button4Click;
    // This method is equivalent to gEdit101's Button4Click()
    var
      sPlainText: string;
      sSerialCipherText: AnsiString;
      sFN: string;
    begin
    Codec2.Reset;
    FFileName_Cipher := FFileName_Plain + '_enc.dat'; // Not a text file. + '_enc.txt' would be wrong.
    Codec2.EncryptFile( FFileName_Plain, FFileName_Cipher);
    Put( 'Double Encrypted serial number is now stored in file "%s"', [FFileName_Cipher]);
    end;
    
    
    function TmfmDoubleEncrypt.ReconstructSerial: string;
    var
      CipherStream, PlainStream: TStream;
      sEncryptedSerial: AnsiString;
    begin
    CipherStream := TFileStream.Create( FFileName_Cipher, fmOpenRead);
    PlainStream  := TMemoryStream.Create;
    try
      Codec2.Reset;
      Codec2.DecryptStream( PlainStream, CipherStream);
      PlainStream.Position := 0;
      SetLength( sEncryptedSerial, PlainStream.Size);
      if Length( sEncryptedSerial) > 0 then
        PlainStream.ReadBuffer( sEncryptedSerial[1], Length( sEncryptedSerial));
      Codec1.Reset;
      Codec1.DecryptString( result, sEncryptedSerial)
    finally
      CipherStream.Free;
      PlainStream.Free
      end
    end;
    
    function TmfmDoubleEncrypt.SelfTest: boolean;
    var
      sRecon: string;
    begin
    Put('Commencing self test...',[]);
    try
      Button1Click;  // 1st encryption
      Button4Click;  // 2nd encryption
      sRecon := ReconstructSerial; // Reconstruction
      result := sSerial = sRecon
    finally
      Put('Finished self test. Result = %s',[BoolToStr( result, True)]);
      end;
    end;
    
    end.
    

    这个单位的dfm是......

    object mfmDoubleEncrypt: TmfmDoubleEncrypt
      Left = 0
      Top = 0
      Caption = 'Double Encrypt'
      ClientHeight = 304
      ClientWidth = 643
      Color = clBtnFace
      Font.Charset = DEFAULT_CHARSET
      Font.Color = clWindowText
      Font.Height = -11
      Font.Name = 'Tahoma'
      Font.Style = []
      OldCreateOrder = False
      DesignSize = (
        643
        304)
      PixelsPerInch = 96
      TextHeight = 13
      object btnGo: TButton
        Left = 8
        Top = 8
        Width = 75
        Height = 25
        Caption = 'Go'
        TabOrder = 0
        OnClick = btnGoClick
      end
      object memoLog: TMemo
        Left = 8
        Top = 39
        Width = 627
        Height = 257
        Anchors = [akLeft, akTop, akRight, akBottom]
        Color = clInfoBk
        ReadOnly = True
        ScrollBars = ssVertical
        TabOrder = 1
      end
      object Codec1: TCodec
        AsymetricKeySizeInBits = 1024
        AdvancedOptions2 = []
        CryptoLibrary = CryptographicLibrary1
        Left = 440
        Top = 112
        StreamCipherId = 'native.StreamToBlock'
        BlockCipherId = 'native.AES-128'
        ChainId = 'native.CBC'
      end
      object Codec2: TCodec
        AsymetricKeySizeInBits = 1024
        AdvancedOptions2 = []
        CryptoLibrary = CryptographicLibrary1
        Left = 536
        Top = 112
        StreamCipherId = 'native.StreamToBlock'
        BlockCipherId = 'native.AES-128'
        ChainId = 'native.CBC'
      end
      object CryptographicLibrary1: TCryptographicLibrary
        Left = 480
        Top = 48
      end
      object dlgSave1: TSaveDialog
        InitialDir = 'C:\Temp'
        Title = 'Choose location to save Authentication Code'
        Left = 440
        Top = 176
      end
      object dlgOpen1: TOpenDialog
        InitialDir = 'C:\'
        Left = 536
        Top = 176
      end
    end