-2

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

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

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

编辑1:

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

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

进一步澄清:

我用于加密字符串的编解码器(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;
4

2 回答 2

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;
于 2013-02-05T23:48:07.977 回答
2

我也很困惑你的问题在问什么。冒着误解您的问题的风险,我假设您正在尝试:

  1. 加密一个字符串;
  2. 将加密的字符串存储在文件中
  3. 加密文件(双重加密)
  4. 反转前面的步骤以重建原始字符串。

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
于 2013-02-06T00:49:38.053 回答