Examples Delphi

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-ff88ea5896f6&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.
.
.
.
begin
CoInitialize(nil);
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 ).
// Encrypt function
.
.
if CoInitialize(nil)=S_FALSE then
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.
function Encrypt_password(decrypted_passwd:widestring):widestring;stdcall;
// Parse out any Carriage Return and Line Feed characters
// You may or may not need this routine. It removes the carriage return and
// line feed characters. This was causing my messages to be encrypted
// improperly.
function RemoveCRLF(eStr:widestring):widestring;
var i:integer;
begin
for i:=1 to Length(eStr) do
if (eStr[i]<>#10) and (eStr[i]<>#13) then
result:=result+eStr[i];
end;
begin
if (decrypted_passwd = '') then
begin
raise TEncryptionError.Create(EncryptionError.M(NO_KEY));
Exit;
end;
Result:='';
dllHandle:= LoadLibrary(LPCTSTR(dllname));
if (dllHandle < HINSTANCE_ERROR) then Exit
else
begin
try try
// Create The EncryptedData object
EnData := TEncryptedData.Create(nil);
// Set the Algorithm Type – See other settings at the end of this document.
EnData.Algorithm.Name:= CAPICOM_ENCRYPTION_ALGORITHM_3DES;
// Set the Key Size – See other settings at the end of this document.
EnData.Algorithm.KeyLength:= CAPICOM_ENCRYPTION_KEY_LENGTH_MAXIMUM;
// Set the Password used for encrypting the message. This same password must be
// used when you want to decrypt this message. You must pass in the
// CAPICOM_SECRET_PASSWORD argument or 0.
EnData.SetSecret(‘Something Secret’,CAPICOM_SECRET_PASSWORD);
// Copy decrypted message to the Contents property. This will be encrypted by
// the encrypt method.
EnData.Content:= decrypted_passwd;
// Encrypt the Contents using a CAPICOM_ENCODING_TYPE and return the encrypted
// string. See other settings at the end of this document.
Result:=RemoveCRLF(EnData.Encrypt(CAPICOM_ENCODE_BASE64));
// Handle Exceptions
except on Exception do
begin
MessageBox(0,'There was a problem during the Encryption phase.', 'Warning',0);
Exit;
end;
end;
finally
// Free the EncryptedData object and DLL handle
EnData.Free;
FreeLibrary(dllhandle);
end;
end;
// Call CoUnitialize if a CoInitialize object is
if CoInitialize(nil)=S_FALSE then
CoUnInitialize; // instanciated.
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.
function decode_password(encoded_passwd:widestring ):widestring;stdcall;
var DeData : TEncryptedData;
begin
if encoded_passwd<>'' then
// Get a handle to Capicom.dll
dllHandle:= LoadLibrary(LPCTSTR(dllname));
if (dllHandle < HINSTANCE_ERROR) then Exit
else
begin
// Create the EncryptedData object
DeData := TEncryptedData.Create(nil);
try try
// Set the Algorithm Type – See other settings at the end of this document.
DeData.Algorithm.Name:= CAPICOM_ENCRYPTION_ALGORITHM_3DES;
// Set the Password used for decrypting the message. The same password must be
// used that was used to encrypt this message. You must pass in the
// CAPICOM_SECRET_PASSWORD argument or 0.
DeData.SetSecret(KEY,CAPICOM_SECRET_PASSWORD);
// Decrypt the Encrypted String. Takes one argument which is the message to be
// decrypted.
DeData.Decrypt(encoded_passwd);
// Check that the Contents property contains a value
if DeData.Content='' then
MessageBox(0,'Decryption failed. The Value was not Decrypted properly.', 'Warning',0)
else
// Return the Decrypted String That is located in the objects content property.
Result:=DeData.Content;
except on Exception do
begin
MessageBox(0,'An Unknown error occured during Decryption. Possible invalid Encrypted value.','Warning',0);
exit;
end;
end;
finally // Free the EncryptedData object and Capicom handle.
DeData.Free;
FreeLibrary(dllhandle);
end;
end;
if CoInitialize(nil)=S_FALSE then // Call CoUnitialize if the CoInitialize object is
CoUnInitialize; // instanciated.
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.