Encryption/Decryption using Microsoft’s Capicom with Borland’s Delphi™
March 2004
Encryption/Decryption using Microsoft’s Capicom with Borland’s Delphi™
This article is for those who wish to learn the proper steps for
encrypting/decrypting using Mirosoft’s Capicom.dll with Borland’s Delphi™
The first thing you need is to install capicom.dll to the machine that will be
performing the encryption and/or decryption. You can download the current
Microsoft SDK from the following site and either install the SDK, or extract
capicom.dll from the capicom.cab file contained within the CC2RINST.exe file.
http://www.microsoft.com/downloads/details.aspx?familyid=860ee43a-a843-462f-abb5-ff8
8ea5896f6&displaylang=en
You then will need to register Capicom.dll using the following command from a dos
window.
C:\> regsvr32 capicom.dll
(If you need to unregister capicom.dll use the /u flag. i.e. regsvr32 /u
capicom.dll).
After you have downloaded Capicom and registered it on your machine, the next step
is to create a type-library with Capicom.dll. To do this ( in Delphi 7 ) first
open your project in Delphi. Then click the Project menu option then choose “Import
Type Library”.
Find the Capicom.Dll in the listing and click the “Create Unit” button.
This will automatically create a capicom type library unit (.pas) and add it to
your project. After you create the unit you should now have a unit called
“CAPICOM_TBL” added to your project. This will allow you to create a capicom
object so you can access the encryption/decryption methods.
The class name for the capicom object is called TEncryptedData. TEncryptedData
contains all the necessary calls to Capicom.dll for the encryption and decryption
processes. But before you start writing any code, you must first add two COM
message calls to your unit CoInitialize() and CoUnInitialize. This is necessary
because Capicom.dll is an ActiveX component. Therefore you need to add the
“ActiveX” unit to your uses clause because this is where the two calls are located.
They must be called at the start and at the end of your application. If your going
to create the TEncryptedData inside an application, then you can call
CoInitialize() in the “Initialization” section and call CoUnInitialize in the
“Finalization” section. If you want to create the TEncryptedData object inside a
.DLL, add CoInitialize() after the begin clause at the end of your .DLL.
.
.
.
1
2 begin
3 CoInitialize(nil);
4 end.
Since a DLL does not use the Initialization or Finalization sections, you will need
to put the call to CoUnInitialize; inside any functions that call any Capicom
methods. ( i.e. Encrypt and Decrypt ).
5
6 // Encrypt function
7 .
8 .
9
10 if CoInitialize(nil)=S_FALSE then
11 CoUnInitialize;
After you have the ActiveX calls in place you can start creating your Encryption
and Decryption functions. The following are the steps for creating an encryption
function followed by a coding example for a .DLL.
• Create a handle to capicom.dll
• Create a TEncryptedData object
• Set the Encryption Algorithm.
• Set the Encryption Length
• Set the SetSecret property.
• Set the Content property.
• Call the Encrypt method.
12
13 function Encrypt_password(decrypted_passwd:widestring):widestring;stdcall;
14 // Parse out any Carriage Return and Line Feed characters
15 // You may or may not need this routine. It removes the carriage return and
16 // line feed characters. This was causing my messages to be encrypted
17 // improperly.
18 function RemoveCRLF(eStr:widestring):widestring;
19 var i:integer;
20 begin
21 for i:=1 to Length(eStr) do
22 if (eStr[i]<>#10) and (eStr[i]<>#13) then
23 result:=result+eStr[i];
24 end;
25 begin
26
27 if (decrypted_passwd = '') then
28 begin
29 raise TEncryptionError.Create(EncryptionError.M(NO_KEY));
30 Exit;
31 end;
32 Result:='';
33 dllHandle:= LoadLibrary(LPCTSTR(dllname));
34 if (dllHandle < HINSTANCE_ERROR) then Exit
35 else
36 begin
37 try try
38 // Create The EncryptedData object
39 EnData := TEncryptedData.Create(nil);
40 // Set the Algorithm Type – See other settings at the end of this document.
41 EnData.Algorithm.Name:= CAPICOM_ENCRYPTION_ALGORITHM_3DES;
42 // Set the Key Size – See other settings at the end of this document.
43 EnData.Algorithm.KeyLength:= CAPICOM_ENCRYPTION_KEY_LENGTH_MAXIMUM;
44 // Set the Password used for encrypting the message. This same password must be
45 // used when you want to decrypt this message. You must pass in the
46 // CAPICOM_SECRET_PASSWORD argument or 0.
47 EnData.SetSecret(‘Something Secret’,CAPICOM_SECRET_PASSWORD);
48 // Copy decrypted message to the Contents property. This will be encrypted by
49 // the encrypt method.
50 EnData.Content:= decrypted_passwd;
51 // Encrypt the Contents using a CAPICOM_ENCODING_TYPE and return the encrypted
52 // string. See other settings at the end of this document.
53 Result:=RemoveCRLF(EnData.Encrypt(CAPICOM_ENCODE_BASE64));
54 // Handle Exceptions
55 except on Exception do
56 begin
57 MessageBox(0,'There was a problem during the Encryption phase.',
58 'Warning',0);
59 Exit;
60 end;
61 end;
62 finally
63 // Free the EncryptedData object and DLL handle
64 EnData.Free;
65 FreeLibrary(dllhandle);
66 end;
67 end;
68
69 // Call CoUnitialize if a CoInitialize object is
70 if CoInitialize(nil)=S_FALSE then
71 CoUnInitialize; // instanciated.
72 end;
The following are the steps for creating a decoding function in a .DLL followed by
a coding example.
• Create a handle to capicom.dll.
• Create a TEncryptedData object.
• Set the Algorithm type.
• Set the SetSecret property.
• Call the Decrypt method with the encrypted message.
• Return the Contents property.
73
74 function decode_password(encoded_passwd:widestring ):widestring;stdcall;
75 var DeData : TEncryptedData;
76 begin
77 if encoded_passwd<>'' then
78 // Get a handle to Capicom.dll
79 dllHandle:= LoadLibrary(LPCTSTR(dllname));
80 if (dllHandle < HINSTANCE_ERROR) then Exit
81 else
82 begin
83 // Create the EncryptedData object
84 DeData := TEncryptedData.Create(nil);
85 try try
86 // Set the Algorithm Type – See other settings at the end of this document.
87 DeData.Algorithm.Name:= CAPICOM_ENCRYPTION_ALGORITHM_3DES;
88 // Set the Password used for decrypting the message. The same password must be
89 // used that was used to encrypt this message. You must pass in the
90 // CAPICOM_SECRET_PASSWORD argument or 0.
91 DeData.SetSecret(KEY,CAPICOM_SECRET_PASSWORD);
92 // Decrypt the Encrypted String. Takes one argument which is the message to be
93 // decrypted.
94 DeData.Decrypt(encoded_passwd);
95 // Check that the Contents property contains a value
96 if DeData.Content='' then
97 MessageBox(0,'Decryption failed. The Value was not Decrypted properly.',
98 'Warning',0)
99 else
100 // Return the Decrypted String That is located in the objects content property.
101 Result:=DeData.Content;
102 except on Exception do
103 begin
104 MessageBox(0,'An Unknown error occured during Decryption. Possible
105 invalid Encrypted value.'
106 exit;
107 end;
108 end;
109 finally // Free the EncryptedData object and Capicom handle.
110 DeData.Free;
111 FreeLibrary(dllhandle);
112 end;
113 end;
114 if CoInitialize(nil)=S_FALSE then // Call CoUnitialize if the CoInitialize object
115 is
116 CoUnInitialize; // instanciated.
117 end;
Capicom Settings
Version 2.0.0.3
Algorithm.Name
Value Meaning
CAPICOM_ENCRYPTION_ALGORITHM_RC2 Use RC2 encryption.
CAPICOM_ENCRYPTION_ALGORITHM_RC4 Use RC4 encryption.
CAPICOM_ENCRYPTION_ALGORITHM_DES Use DES encryption.
CAPICOM_ENCRYPTION_ALGORITHM_3DES Use triple DES encryption.
CAPICOM_ENCRYPTION_ALGORITHM_AES Use the AES algorithm.
Algorithm.KeyLength
Value Meaning
CAPICOM_ENCRYPTION_KEY_LENGTH_MAXIMUM Use the maximum key length available with the
indicated encryption algorithm.
CAPICOM_ENCRYPTION_KEY_LENGTH_40_BITS Use 40-bit keys.
CAPICOM_ENCRYPTION_KEY_LENGTH_56_BITS Use 56-bit keys if available.
CAPICOM_ENCRYPTION_KEY_LENGTH_128_BITS Use 128-bit keys if available.
CAPICOM_ENCRYPTION_KEY_LENGTH_192_BITS Use 192-bit keys. This key length is
available only for AES.
CAPICOM_ENCRYPTION_KEY_LENGTH_256_BITS Use 256-bit keys. This key length is
available only for AES.
CAPICOM_ENCODING_TYPE
Value Meaning
CAPICOM_ENCODE_ANY Data is saved as a base64-encoded string or a pure binary
sequence. This encoding type is used only for input data that has an unknown
encoding type. Introduced in CAPICOM 2.0.
CAPICOM_ENCODE_BASE64 Data is saved as a base64-encoded string.
CAPICOM_ENCODE_BINARY Data is saved as a pure binary sequence.
|