Author: david bolton
How to load and save encrypted string lists
Answer:
I combined routines from two open source projects to produce a simple way of saving
a stringlist to disk in a compressed and very securely encrypted fashion (using the
AES algorithm).
The two components are LockBox from Turbopower - available at
http://sourceforge.net/projects/tplockbox/
http://sourceforge.net/projects/tplockbox/
and UCL Compression Library API for Borland Delphi from
http://www.zeitungsjunge.de/delphi/ucl/index.htm
http://www.zeitungsjunge.de/delphi/ucl/index.htm
The unit EncCompress is listed below. It defines a simple class TCompEnc which lets
you load a text file into the stringlist. To save a plain text string list, first
compress it using the UCLCompressStream, then feed this into the lockbox encryption
component and save that to disk. Loading the encrypted file back in is just a
matter of reversing the process, load the file, decrypt it then decompress it.
I've provided a simple test program - just drop a couple of buttons onto a form and
hook up the click event to these routines. Make sure that the text for the key is
the same in both!! You'll need a test file 'test.txt', and after clicking both
buttons you should find that the 'test2.txt' that is output is identical to the
original.
I appreciate I've done two things which aren't very good- one use an internal
member directly (enc.flist) and used a tMemoryStream to save and load files from
disk instead of a TFileStream (before anyone points these out!)
Note: the AES (Rijndael) is symmetric so the same key encrypts and decrypts.
1 // Sample event handler code
2
3 procedure TForm1.Button1Click(Sender: TObject);
4 var
5 enc: TCompEnc;
6 list: tstringlist;
7 begin
8 Enc := TCompEnc.Create;
9 list := tstringlist.create;
10 list.LoadFromFile('test.txt');
11 enc.flist.Text := list.text;
12 enc.KeyText := 'hgjhgkjghkjh654328878';
13 enc.SaveToFile('test.dat');
14 enc.free;
15 list.free;
16 end;
17
18 procedure TForm1.Button2Click(Sender: TObject);
19 var
20 enc: TCompEnc;
21 begin
22 Enc := TCompEnc.Create;
23 Enc.KeyText := 'hgjhgkjghkjh654328878';
24 Enc.LoadFromfile('test.dat');
25 Enc.Flist.SaveToFile('test2.txt');
26 Enc.free;
27 end;
28
29 // The unit
30 unit EncCompress;
31
32 interface
33
34 uses
35 Windows, SysUtils, Classes, diuclstreams, LbCipher, LbClass;
36
37 type
38 TCompEnc = class
39 FList: TStringList;
40 FKeyText: string;
41 private
42 function GetList: TStringlist;
43 procedure SetKeyText(const Value: string);
44
45 public
46 constructor Create;
47 destructor Destroy; override;
48 procedure LoadFromFile(Filename: string);
49 procedure SaveToFile(Filename: string);
50 property List: TStringlist read GetList;
51 property KeyText: string write SetKeyText;
52 end;
53
54 implementation
55
56 uses math;
57
58 const
59 COMPRESSION_LEVEL = 3;
60 BUFFER_SIZE = $4000;
61
62 { TCompEnc }
63
64 constructor TCompEnc.Create;
65 begin
66 inherited;
67 Flist := TStringList.Create;
68 end;
69
70 destructor TCompEnc.Destroy;
71 begin
72 FList.Free;
73 inherited;
74 end;
75
76 function TCompEnc.GetList: TStringlist;
77 begin
78 Result := Flist;
79 end;
80
81 // Step 1 Compress Flist Strings into stream
82 // Compress stream
83 // Save stream to file.
84
85 procedure TCompEnc.SaveToFile(Filename: string);
86 var
87 Str: TStringStream;
88 CompStream: TMemoryStream;
89 FileStream: TMemoryStream;
90 MyCipher: TLbRijndael;
91 begin
92 MyCipher := TLbRijnDael.Create(nil);
93 MyCipher.GenerateKey(FKeyText);
94
95 Str := tStringStream.Create(Flist.Text);
96 Str.Position := 0;
97 CompStream := TMemoryStream.create;
98 UclCompressStream(Str, CompStream, 3, BUFFER_SIZE);
99 Str.Free;
100 CompStream.Position := 0;
101 try
102 // Prepare key...
103 Filestream := tmemoryStream.Create;
104 MyCipher.EncryptStream(CompStream, FileStream);
105 FileStream.Position := 0;
106 FileStream.SaveToFile(Filename);
107 FileStream.Free;
108 finally
109 CompStream.Free;
110 end;
111 end;
112
113 // Loads File.
114 // 1st step, decrypt from AES to just Compressed
115 // 2nd step, Decompress into flist
116
117 procedure TCompEnc.LoadFromFile(Filename: string);
118 var
119 Source, Dest: TMemoryStream;
120 MyCipher: TLbRijnDael;
121 begin
122 // Decryption
123 Source := TMemoryStream.Create;
124 Source.LoadFromFile(Filename);
125 Source.Position := 0;
126 Dest := TMemoryStream.Create;
127 MyCipher := TLbRijnDael.Create(nil);
128 MyCipher.GenerateKey(FKeyText);
129
130 try
131 MyCipher.DecryptStream(Source, Dest);
132 MyCipher.Free;
133 Dest.Position := 0;
134 Source.Position := 0;
135
136 if UclDecompressStream(Dest, Source, BUFFER_SIZE) then
137 begin
138 Flist.Clear;
139 Source.Position := 0;
140 Flist.LoadFromStream(Source);
141 end;
142 finally
143 Dest.Free;
144 end;
145 Source.Free;
146 end;
147
148 procedure TCompEnc.SetKeyText(const Value: string);
149 begin
150 FKeyText := Value;
151 end;
152
153 end.
|