Sign in Join
Wiki copytemporary

DCPcrypt: what changed

Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.

Title: DCPcrypt

OldNewLine
1+### About
2+
3+DCPcrypt is a collection of cryptographic components for the Lazarus.
4+
5+The idea behind DCPcrypt is that it should be possible to "drop in" any algorithm implementation to replace another with minimum or no code changes. To aid in this goal all cryptographic components are descended from one of several base classes, TDCP_cipher for encryption algorithms and TDCP_hash for message digest algorithms.
6+
7+Since v2.0.4 it compiles with FPC 2.4.1 and has been tested under 32-bit & 64-bit Linux and 32-bit Windows.
8+
9+- Status: Production/Stable
10+- Latest version: 2.0.4.1
11+
12+Notice that DCPcrypt does not have an (un)official maintainer anymore.
13+
14+Screenshots:
15+
16+<figure>
17+<img src="Dcp1.png" title="Dcp1.png" />
18+<figcaption>Dcp1.png</figcaption>
19+</figure>
20+
21+<figure>
22+<img src="Dcp2.png" title="Dcp2.png" />
23+<figcaption>Dcp2.png</figcaption>
24+</figure>
25+
26+### Author(s)
27+
28+- David Barton, [home page](http://www.cityinthesky.co.uk)
29+
30+Contributors:
31+
32+- Port to Lazarus by [barko](http://wiki.freepascal.org/User:Barko) - 2006
33+- [Graeme Geldenhuys](http://geldenhuys.co.uk) - 2009
34+
35+### License
36+
37+The MIT License
38+
39+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
40+
41+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
42+
43+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
44+
45+### Download
46+
47+Since March 2010, DCPCrypt source code is hosted as part of the [Lazarus-CCR project](http://sourceforge.net/projects/lazarus-ccr/) on SourceForge.net.
48+
49+DCPCrypt is also hosted in a [Git](http://git-scm.com) repository. To download the latest source code from the repository you need to run the following command.
50+
51+`git clone `[`git://lazarus-ccr.git.sourceforge.net/gitroot/lazarus-ccr/dcpcrypt`](git://lazarus-ccr.git.sourceforge.net/gitroot/lazarus-ccr/dcpcrypt)
52+
53+`git clone http://git.code.sf.net/p/lazarus-ccr/dcpcrypt lazarus-ccr-dcpcrypt`
54+
55+After that you can stay updated by simply running
56+
57+`git pull`
58+
59+### Installation
60+
61+Since the v2.0.4 release, DCPCrypt is split into two packages:
62+
63+dcpcrypt.lpk
64+This is a run-time only package and only contains the core non-gui code. You can use the package for console applications or other non-LCL projects (eg: fpGUI or MSEgui based projects).
65+
66+dcpcrypt_laz.lpk
67+This is the design time package to register the various components with the Lazarus IDE component palette.
68+
69+To use DCPCrypt with Lazarus IDE for the first time:
70+
71+- In 'Package \> Open Package File', open dcpcrypt.lpk and click **Compile**
72+- If you want to register the DCPCrypt components with the Lazarus IDE component palette, open the dcpcrypt_laz.lpk and click **Compile** and then **Install**. Lazarus IDE will now rebuild itself.
73+- Restart Lazarus IDE and you are ready to use DCPCrypt.
74+
75+### Usage
76+
77+Please note that an appreciation of the basic principles of encryption/decryption and key management is needed to ensure the correct usage of the ciphers implemented within this package. A good introduction on this subject is provided by Bruce Schneier's "Applied Cryptography" (ISBN: 0-471-11709-9) also see the NIST publication SP800-38A for information on the block cipher chaining modes.
78+
79+- Ciphers - the basic building block of DCPcrypt, the TDCP_cipher component.
80+- Block Ciphers - the base of all block ciphers, the TDCP_blockcipher component.
81+- Hashes - the base of all hash algorithms, the TDCP_hash component.
82+
83+See included documentation.
84+
85+#### Encrypting using plain key
86+
87+Normally, for encryption, dpcpcrypt expects keys that are hashed when they are supplied through *.InitStr*.
88+
89+You can pass a plain string key by using *[.Init](http://is.muni.cz/th/51468/fi_b/priloha/DCPcrypt/Docs/Ciphers.html#Init)*, e.g. like this:
90+
91+``` pascal
92+var s:string;
93+begin
94+ s:='1234567890ABCDEF1234567890ABCDEF';
95+ DCP_3des1.Init(s[1],length(s)*8,nil);
96+```
97+
98+Source: [forum thread](http://lazarus.freepascal.org/index.php/topic,18108.msg101683.html#msg101683).
99+
100+#### Lazarus example
101+
102+``` pascal
103+unit Unit1;
104+
105+{$mode objfpc}{$H+}
106+
107+interface
108+
109+uses
110+ Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
111+ DCPrc4, DCPsha1;
112+
113+type
114+
115+ { TForm1 }
116+
117+ TForm1 = class(TForm)
118+ Button1: TButton;
119+ Button2: TButton;
120+ DCP_rc4_1: TDCP_rc4;
121+ DCP_sha1_1: TDCP_sha1;
122+ Edit1: TEdit;
123+ Edit2: TEdit;
124+ Label1: TLabel;
125+ Label2: TLabel;
126+ procedure Button1Click(Sender: TObject);
127+ procedure Button2Click(Sender: TObject);
128+ procedure FormCreate(Sender: TObject);
129+ private
130+ { private declarations }
131+ public
132+ { public declarations }
133+ end;
134+
135+var
136+ Form1: TForm1;
137+ KeyStr: string;
138+
139+implementation
140+
141+{$R *.lfm}
142+
143+{ TForm1 }
144+
145+procedure TForm1.Button1Click(Sender: TObject);
146+var
147+ Cipher: TDCP_rc4;
148+ Source, Dest: TFileStream;
149+ begin
150+ //if InputQuery('Passphrase','Enter passphrase',KeyStr) then // get the passphrase
151+ begin
152+ try
153+ Source:= TFileStream.Create(Edit1.Text,fmOpenRead); // Edit1.Text, PATH SOURCE OF FILE
154+ Dest:= TFileStream.Create(Edit2.Text,fmCreate); // Edit2.Text, PATH DESTINATION OF FILE
155+ Cipher:= TDCP_rc4.Create(Self);
156+ Cipher.InitStr(KeyStr,TDCP_sha1); // initialize the cipher with a hash of the passphrase
157+ Cipher.EncryptStream(Source,Dest,Source.Size); // encrypt the contents of the file
158+ Cipher.Burn;
159+ Cipher.Free;
160+ Dest.Free;
161+ Source.Free;
162+ MessageDlg('File encrypted',mtInformation,[mbOK],0);
163+ except
164+ MessageDlg('File IO error',mtError,[mbOK],0);
165+ end;
166+ end;
167+ end;
168+
169+procedure TForm1.Button2Click(Sender: TObject);
170+var
171+ Cipher: TDCP_rc4;
172+ //KeyStr: string;
173+ Source, Dest: TFileStream;
174+ begin
175+ //if InputQuery('Passphrase','Enter passphrase',KeyStr) then // get the passphrase
176+ begin
177+ try
178+ Source:= TFileStream.Create(Edit1.Text,fmOpenRead); // Edit1.Text, PATH SOURCE OF FILE
179+ Dest:= TFileStream.Create(Edit2.Text,fmCreate); // Edit2.Text, PATH DESTINATION OF FILE
180+ Cipher:= TDCP_rc4.Create(Self);
181+ Cipher.InitStr(KeyStr,TDCP_sha1); // initialize the cipher with a hash of the passphrase
182+ Cipher.DecryptStream(Source,Dest,Source.Size); // decrypt the contents of the file
183+ Cipher.Burn;
184+ Cipher.Free;
185+ Dest.Free;
186+ Source.Free;
187+ MessageDlg('File decrypted',mtInformation,[mbOK],0);
188+ except
189+ MessageDlg('File IO error',mtError,[mbOK],0);
190+ end;
191+ end;
192+ end;
193+
194+procedure TForm1.FormCreate(Sender: TObject);
195+begin
196+ KeyStr := 'casa777'; // my password
197+end;
198+
199+end.
200+```
201+
202+<figure>
203+<img src="dcrypt_form.jpg" title="dcrypt_form.jpg" />
204+<figcaption>dcrypt_form.jpg</figcaption>
205+</figure>
206+
207+### Bugs
208+
209+If you are using DCPrijndael, be advised that key sizes that are not in the AES standard are known to produce key schedules that are **not** inter-operable with other Rijndael implementations. Few implementations provide the non-standard key (or block) sizes. [Brian Gladman](https://web.archive.org/web/20090201173123/http://fp.gladman.plus.com/cryptography_technology/rijndael/) and [Jeffrey Clement](https://web.archive.org/web/20110826031605/http://jclement.ca/software/pyrijndael/) provide implementations (C and Python) that are known to be incompatible with DCPrijndael for non-standard key sizes. Test program provided below with comments showing the expect results:
210+
211+``` pascal
212+program ctst;
213+{$mode objfpc}{$H+}
214+uses
215+ {$IFDEF UNIX}{$IFDEF UseCThreads}
216+ cthreads,
217+ {$ENDIF}{$ENDIF}
218+ Sysutils, DCPrijndael;
219+const
220+ InData: array[0..15] of byte =
221+ ($32,$43,$f6,$a8,$88,$5a,$30,$8d,$31,$31,$98,$a2,$e0,$37,$07,$34);
222+ Key1: array[0..19] of byte =
223+ ($2b,$7e,$15,$16,$28,$ae,$d2,$a6,$ab,$f7,$15,$88,$09,$cf,$4f,$3c,$76,$2e,$71,$60);
224+ Key2: array[0..31] of byte =
225+ ($2b,$7e,$15,$16,$28,$ae,$d2,$a6,$ab,$f7,$15,$88,$09,$cf,$4f,$3c,$76,$2e,$71,$60,
226+ $f3,$8b,$4d,$a5,$6a,$78,$4d,$90,$45,$19,$0c,$fe);
227+ OutData1: array[0..15] of byte =
228+ ($23,$1d,$84,$46,$39,$b3,$1b,$41,$22,$11,$cf,$e9,$37,$12,$b8,$80);
229+ OutData2: array[0..15] of byte =
230+ ($1a,$6e,$6c,$2c,$66,$2e,$7d,$a6,$50,$1f,$fb,$62,$bc,$9e,$93,$f3);
231+var
232+ Cipher: TDCP_rijndael;
233+ Block: array[0..15] of byte;
234+begin
235+// lengths: block = 16 bytes, key = 20 bytes
236+// key = 2b7e151628aed2a6abf7158809cf4f3c762e7160
237+// input = 3243f6a8885a308d313198a2e0370734
238+// encrypt = 231d844639b31b412211cfe93712b880
239+// decrypt = 3243f6a8885a308d313198a2e0370734
240+ Cipher := TDCP_rijndael.Create(nil);
241+ Cipher.Init(Key1, Sizeof(Key1) * 8, nil);
242+ Cipher.EncryptECB(InData, Block);
243+ writeln('128-bit block & 160-bit key results:');
244+ writeln(boolean(CompareMem(@Block, @OutData1, 16)));
245+ Cipher.DecryptECB(Block, Block);
246+ writeln(boolean(CompareMem(@Block, @InData, 16)));
247+ Cipher.Free;
248+// lengths: block = 16 bytes, key = 32 bytes
249+// key = 2b7e151628aed2a6abf7158809cf4f3c762e7160f38b4da56a784d9045190cfe
250+// input = 3243f6a8885a308d313198a2e0370734
251+// encrypt = 1a6e6c2c662e7da6501ffb62bc9e93f3
252+// decrypt = 3243f6a8885a308d313198a2e0370734
253+ Cipher := TDCP_rijndael.Create(nil);
254+ Cipher.Init(Key2, Sizeof(Key2) * 8, nil);
255+ Cipher.EncryptECB(InData, Block);
256+ writeln('128-bit block & 256-bit key results:');
257+ writeln(boolean(CompareMem(@Block, @OutData2, 16)));
258+ Cipher.DecryptECB(Block, Block);
259+ writeln(boolean(CompareMem(@Block, @InData, 16)));
260+ Cipher.Free;
261+end.
262+```
263+
264+The output that freepascal 2.2.0 produces is:
265+
266+` 128-bit block & 160-bit key results:`\
267+` FALSE`\
268+` TRUE`\
269+` 128-bit block & 256-bit key results:`\
270+` TRUE`\
271+` TRUE`
272+
273+What this meas is that using 160-bit keys you can only decrypt the output with DCPrijndael, but it won't work with other implementations. On the other hand, 256-bit keys are interoperable. The 160-bit case is important because SHA-1 outputs 160-bit hashes, which makes it a convenient way to generate a key from a password, so it's used by some (hardware) systems.
274+
275+### External links
276+
277+- [HMAC/PBKDF1/PBKDF2](http://keit.co/p/dcpcrypt-hmac-rfc2104/) implementation based on DCPcrypt.
278+
279+---
280+*From the Free Pascal wiki, page "DCPcrypt", as it stood on 2022-01-13 after a change by Trev, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*
281+Category: Components
282+Category: Lazarus-CCR

Back to history