Microsoft KB Archive/821762

= How to encrypt a string in Visual Basic 6.0 and how to decrypt the string in Visual Basic .NET or in Visual Basic 2005 =

Article ID: 821762

Article Last Modified on 5/18/2007

-

APPLIES TO


 * Microsoft Visual Basic 2005
 * Microsoft Visual Basic .NET 2003 Standard Edition
 * Microsoft Visual Basic .NET 2002 Standard Edition
 * Microsoft Visual Basic 6.0 Professional Edition

-



SUMMARY
''This article describes how to encrypt a string by using Microsoft Visual Basic 6.0. It also describes how to decrypt the string by using Visual Basic .NET. Additionally, this article discusses Microsoft Windows APIs that are used in the code for the encryption process and for the decryption process.''



IN THIS TASK

 * INTRODUCTION
 * Requirements
 * Code for encryption and for decryption
 * Encryption in Visual Basic 6.0
 * CryptWrap DLL
 * CryptoWrap DLL
 * Variables declaration
 * API declaration in Visual Basic 6.0
 * Important functions
 * Encryption process
 * Encrypt program
 * User interface
 * Important function
 * DecryptInVBNET program
 * User interface
 * Important function
 * Instructions to run the code
 * Encrypt program
 * DecryptInVBNET program
 * REFERENCES



INTRODUCTION
This step-by-step article describes how to encrypt a string by using CryptoAPI in Microsoft Visual Basic 6.0. It also describes how to decrypt the string by using the CryptoServiceProvider classes in Microsoft Visual Basic .NET or in Microsoft Visual Basic 2005. This article discusses the code for the encryption process in Visual Basic 6.0. It also discusses the code for the decryption process in Visual Basic .NET or in Visual Basic 2005.

The encryption process code and the decryption process code have the following structures:
 * Encryption process code - When you develop encryption code by using Visual Basic 6.0, the code is structured in one project group that is named EncryptGroup. This project group contains the following individual projects:
 * CryptWrap.vbp - The CryptWrap.vbp project contains a Visual Basic class file that is named clsCryptoAPI.cls.
 * Encrypt.vbp - The Encrypt.vbp project contains a form that is named frmEncFiles.frm.
 * Decryption process code - When you develop decryption code by using Visual Basic .NET or in Visual Basic 2005, the code is structured in one solution that is named DecryptInVBNET. This solution contains one Microsoft Windows application project that is named DecryptInVBNET.vbproj. This project contains one Windows Form that is named Form1.vb.

back to the top

Requirements
This article assumes that you are familiar with the following topics:
 * Cryptography
 * Using APIs in Visual Basic 6.0
 * Using the CryptoServiceProvider classes in Visual Basic .NET or in Visual Basic 2005

The following list outlines the recommended hardware, software, network infrastructure, and service packs that you need:
 * Microsoft Windows Server 2003, Microsoft Windows 2000, or Microsoft Windows XP
 * Microsoft Visual Basic 6.0 and Microsoft Visual Basic .NET and Microsoft Visual Basic 2005

back to the top

Code for encryption and for decryption
This article describes the code that is included in the CryptographySample.exe package.

The following file is available for download from the Microsoft Download Center:

Download the CryptographySample.exe package now.

For additional information about how to download Microsoft Support files, click the following article number to view the article in the Microsoft Knowledge Base:

119591 How to Obtain Microsoft Support Files from Online Services

Microsoft scanned this file for viruses. Microsoft used the most current virus-detection software that was available on the date that the file was posted. The file is stored on security-enhanced servers that help to prevent any unauthorized changes to the file.

Note To use the downloaded sample code, follow the steps in the &quot;Instructions to run the code&quot; section.

back to the top

Encryption in Visual Basic 6.0
This section describes the important steps in the encryption process. It also describes the Visual Basic code that is used for these steps.

back to the top

CryptWrap DLL
The CryptWrap DLL is included with the code that you downloaded in the &quot;Code for encryption and for decryption&quot; section. The CryptWrap DLL is a wrapper that wraps around the API calls. The CryptWrap DLL is in the CryptWrap.vbp project that is in the EncryptGroup project group.

The encryption process requires the CryptWrap DLL. The Encrypt project uses the CryptWrap DLL to call the functions that perform the actual encryption.

back to the top

CryptoWrap DLL
The CryptoWrap DLL is coded by using an ActiveX DLL project template. The CryptoWrap DLL is in the clsCryptoAPI.cls file that is in the EncryptGroup project group.

The code of the CryptoWrap DLL contains the following:
 * Declarations of variables and of constants that the CryptoWrap DLL uses.
 * Declarations of subroutines and of functions for the Cryptography API function from the Advapi32.dll library file in terms of Visual Basic 6.0.
 * Declarations of properties, of functions, and of subroutines.
 * A password that is assigned to a module-level variable in the code from the calling program.

Note This password is used to derive the key that the CryptoEncrypt function uses to encrypt the string.

The CryptoWrap DLL uses the SHA1 algorithm for hashing and uses the RC2 algorithm for encryption.

back to the top

Variables declaration
This section describes the important variables that are declared in the clsCryptoAPI.cls file.

Together with the typical variables that you may use for string input and for string output, some other constants are declared in the encryption process code. These other constants are used to call API functions in the CryptWrap.vbp project. Descriptions of some of these other constants appear in the following sample code: Private Const ALG_CLASS_ANY    As Long = 0 Private Const ALG_TYPE_ANY     As Long = 0 Private Const ALG_CLASS_HASH   As Long = 32768 Private Const ALG_TYPE_BLOCK   As Long = 1536 Private Const ALG_CLASS_DATA_ENCRYPT As Long = 24576 Private Const ALG_SID_RC2      As Long = 2 Private Const ALG_SID_SHA1     As Long = 4 ' Hash algorithms Private Const CALG_SHA1        As Long = ALG_CLASS_HASH Or ALG_TYPE_ANY Or ALG_SID_SHA1 ' Block ciphers Private Const CALG_RC2         As Long = ALG_CLASS_DATA_ENCRYPT Or ALG_TYPE_BLOCK Or ALG_SID_RC2 ' CryptSetProvParam Private Const PROV_RSA_FULL       As Long = 1 ' used when acquiring the provider Private Const CRYPT_VERIFYCONTEXT As Long = &HF0000000 ' Microsoft provider data Private Const MS_DEFAULT_PROVIDER As String = _ &quot;Microsoft Base Cryptographic Provider v1.0&quot; ' used to specify not to use any salt value while deriving the key Private Const CRYPT_NO_SALT As Long = &H10 The Wincrypt.h header file on your computer contains the definitions of all these other constants. You can use the Wincrypt.h header file directly in your C or C++ project code. However, in the Visual Basic 6.0 program that you downloaded in the &quot;Code for encryption and for decryption&quot; section, the constants that the encryption process uses are declared and are initialized in the clsCryptoAPI.cls file. These constants are the same constants that are declared in the Wincrypt.h file on your computer.

back to the top

API declaration in Visual Basic 6.0
The important API functions that are declared in the clsCryptoAPI.cls file are the following:   GetLastError - The GetLastError function retrieves the calling thread's last error code value.

The following code is an example of the GetLastError function: Private Declare Function GetLastError Lib &quot;kernel32&quot; As Long   CryptAcquireContext - The CryptAcquireContext function is used to acquire a handle to a specified key container in a specified cryptographic service provider (CSP). The phProv parameter receives the handle to the specified key container. You can use this handle to call other API functions.

The following code is an example of the CryptAcquireContext function: Private Declare Function CryptAcquireContext Lib &quot;advapi32.dll&quot; _ Alias &quot;CryptAcquireContextA&quot; (ByRef phProv As Long, _             ByVal pszContainer As String, ByVal pszProvider As String, _              ByVal dwProvType As Long, ByVal dwFlags As Long) As Long   CryptCreateHash - The CryptCreateHash function is used to initiate the hashing of a stream of data. The CryptCreateHash function returns to the caller a handle to a CSP hash object. This handle can also be used in later calls to the CryptHashData function to hash the session key. The phHash parameter receives the handle of the new hash object.

The following code is an example of the CryptCreateHash function: Private Declare Function CryptCreateHash Lib &quot;advapi32.dll&quot; _ (ByVal hProv As Long, ByVal algid As Long, _             ByVal hkey As Long, ByVal dwFlags As Long, _              ByRef phHash As Long) As Long   CryptHashData - The CryptHashData function adds data to a specified hash object. The pbData parameter contains the data to be hashed.

The following code is an example of the CryptHashData function: Private Declare Function CryptHashData Lib &quot;advapi32.dll&quot; _ (ByVal hhash As Long, ByVal pbData As String, _             ByVal dwDataLen As Long, ByVal dwFlags As Long) As Long   CryptDestroyHash - The CryptDestroyHash function destroys the hash object that the hHash parameter references.

The following code is an example of the CryptDestroyHash function: Private Declare Function CryptDestroyHash Lib &quot;advapi32.dll&quot; _ (ByVal hhash As Long) As Long   CryptReleaseContext - The CryptReleaseContext function is used to release a handle to a CSP and to a key container. The hProv parameter is the handle to the CSP. The value of the hProv parameter is obtained by calling the CryptAcquireContext API function.

The following code is an example of the CryptReleaseContext function: Private Declare Function CryptReleaseContext Lib &quot;advapi32.dll&quot; _ (ByVal hProv As Long, ByVal dwFlags As Long) As Long   CryptDeriveKey - The CryptDeriveKey function generates a cryptographic key that is derived from base data. The CryptDeriveKey function always generates the same key for the same base data if you use the same CSP and the same algorithms every time that you call the CryptDeriveKey function for the same base data.

The base data can be a password. You can hash the password and then call this function to obtain a handle to the key. The phKey parameter receives the handle to the key that is used for the encryption.

The following code is an example of the CryptDeriveKey function: Private Declare Function CryptDeriveKey Lib &quot;advapi32.dll&quot; _ (ByVal hProv As Long, ByVal algid As Long, _             ByVal hBaseData As Long, ByVal dwFlags As Long, _              ByRef phKey As Long) As Long </li>  CryptDestroyKey - The CryptDestroyKey function releases the handle that the hKey parameter references. The following code is an example of the CryptDestroyKey function: Private Declare Function CryptDestroyKey Lib &quot;advapi32.dll&quot; _ (ByVal hkey As Long) As Long </li>  CryptEncrypt - The CryptEncrypt function is used to encrypt data. The key that the CSP module holds designates the algorithm that is used to encrypt the data. The hKey parameter references this key. The following code is an example of the CryptEncrypt function: Private Declare Function CryptEncrypt Lib &quot;advapi32.dll&quot; _ (ByVal hkey As Long, ByVal hhash As Long, ByVal Final As Long, _             ByVal dwFlags As Long, ByVal pbData As String, _              ByRef pdwDataLen As Long, ByVal dwBufLen As Long) As Long </li></ul>

The CopyMemory subroutine is also declared in the clsCryptoAPI.cls file. The CopyMemory subroutine copies a block of memory from one location to another location. The CopyMemory subroutine takes the following parameters:
 * dest - The dest parameter is the destination where the content is copied to.
 * source - The source parameter is the source where the content is copied from.
 * bytes - The bytes parameter is the size of the content to be copied from the source to destination.

The following code is an example of the CopyMemory subroutine: Private Declare Sub CopyMemory Lib &quot;kernel32&quot; Alias &quot;RtlMoveMemory&quot; _ (dest As Any, source As Any, ByVal bytes As Long) back to the top

Important functions
This section describes some important functions that are declared in the clsCryptoAPI.cls file.

The Encrypt program calls the Encrypt function to encrypt a string. The following code is an example of the Encrypt function: Public Function Encrypt(Optional intHashType As Integer = 1, _                           Optional intCipherType As Integer = 1) As Boolean Encrypt = CryptoEncrypt(intHashType, intCipherType) End Function This function has two optional parameters. The intHashType parameter specifies the hashing algorithm to be used to derive the key. The intCipherType parameter specifies the cipher type that the Encrypt program uses to encrypt the string.

Note The cipher type is also known as the encryption algorithm.

Because these parameters are optional, they are initialized to their default values. Therefore, if the calling program does not provide the values for these parameters, the Encrypt function uses the default values.

The Encrypt function calls the CryptoEncrypt function. The CryptoEncrypt function is a private function of the CryptoWrap DLL that performs the actual encryption. The following code is an example of the CryptoEncrypt function: Private Function CryptoEncrypt(intHashType As Integer, _                                  intCipherType As Integer) As Boolean The CryptoEncrypt function is the main function in the CryptoWrap DLL. The CryptoEncrypt function encrypts the string.

back to the top

Encryption process
The following steps describe the encryption process: <ol> The CryptoEncrypt function starts the encryption process by calling the GetProvider function.

Note The GetProvider function is a private function.</li> The GetProvider function calls the CryptAcquireContext API function to obtain the handle of the CSP.</li> The GetProvider function calls the CryptCreateHash API function to obtain a handle of the hash object.</li> The CryptHashData API function hashes the password text by using the handle that the GetProvider function obtained in step 3.</li> The CryptoEncrypt function calls the CryptDeriveKey API function, and then the CryptDeriveKey API function use the handles that the GetProvider function obtained in steps 2 and 3 to derive the key for encryption.</li> The CryptoEncrypt function calls the CryptDestroyHash API function to destroy the hash object.</li>  A variable initialization statement allocates sufficient space for the buffer where the encrypted string will be stored. For example, the following string will allocate sufficient space: lngEnctBuffLen=lngEncDataLength*2 </li> The CryptoEncrypt function calls the CryptEncrypt API function. The input for the CryptEncrypt API function is the key that the CryptDeriveKey API function derived in step 5 and the string that you want to encrypt.</li> The CryptEncrypt API function stores the encrypted string by overwriting the input string in the buffer.</li> The CryptoEncrypt function calls the CryptDestroyKey API function to destroy the key.</li> The CryptoEncrypt function calls the CryptDestroyHash API function to destroy the hash object.</li></ol>

back to the top

Encrypt program
The Encrypt program is included with the code that you downloaded in the &quot;Code for encryption and for decryption&quot; section. The Encrypt program creates the user interface for the encryption process. It uses the CryptWrap DLL to encrypt strings. This Encrypt program is in the Encrypt project that is a part of the EncryptGroup project group.

back to the top

User interface
The user interface of the Encrypt program contains the following text boxes:
 * Enter full path\filename for a file to encrypt
 * Name and location of encrypted file

Note This text box is read-only.

The user interface of the Encrypt program also contains the following buttons:
 * Encrypt
 * Exit

After you type the correct information in the Enter full path\filename for a file to encrypt box, the path of the file where the encrypted string will be stored appears in the Name and location of encrypted file box.

To start the encryption process, click Encrypt. After the encryption process has completed, you receive a message box that indicates whether the encryption process has succeeded.

To quit the Encrypt program, click Exit.

back to the top

Important function
The following function is declared in the frmEncFiles.frm file of the Encrypt program: Private Sub Encrypt_File This function is called when you click Encrypt. This function call does the following:
 * Creates an object of the clsCryptoAPI class in the CryptoWrap DLL.
 * Performs the basic validation tasks, such as verifying the existence of the file.
 * Initializes the password field and the InputData field of the clsCryptoAPI class object.
 * Calls the Encrypt function of the clsCryptoAPI class object.

Note In the clsCryptoAPI class object, the intHashType parameter is set to the SHA1 algorithm value 4, and the intCipherType parameter is set to the RC2 algorithm value 2.
 * Populates the OutputData field of the clsCryptoAPI class object.

The program receives the encrypted string and then stores it in the output file. You then receive a message box that indicates whether the encryption process has succeeded.

back to the top

DecryptInVBNET program
The DecryptInVBNET program is included with the code that you downloaded in the &quot;Code for encryption and for decryption&quot; section. The DecryptInVBNET program creates the user interface for the decryption. It also uses the Microsoft Visual Studio .NET or Microsoft Visual Studio 2005 CSPs for the decryption process.

back to the top

User interface
The user interface of the DecryptInVBNET program contains the following text boxes:
 * Enter full path\filename for a file to decrypt
 * Name and location of decrypted file

Note This text box is read-only.

The user interface of the DecryptInVBNET program also contains the following buttons:
 * Decrypt
 * Exit

After you type the correct information in the Enter full path\filename for a file to decrypt box, the path of the file where the decrypted string will be stored appears in the Name and location of decrypted file box.

To start the decryption process, click Decrypt. After the decryption process has completed, you receive a message box that indicates whether the decryption process has succeeded.

To quit the DecryptInVBNET program, click Exit.

back to the top

Important function
The following function is declared in the Form1.vb file of the DecryptInVBNET program: Private Sub Decrypt_File This function is called when you click Decrypt. This function call does the following:
 * Creates an object of the CspParameter class. This object is used to pass the parameter to the CSP that performs the cryptographic computations.
 * Creates an object of PasswordDeriveBytes class. This object is used to derive a key from the specified password.

Note For simplicity, the password is hard-coded in the program.
 * Calls the CryptDeriveKey method of the PasswordDeriveBytes class. This method gives the key as the output data. The key is based on the input data.

This program uses the SHA1 algorithm for hashing and uses the RC2 algorithm for encryption. It also creates an object of the RC2CryptoServiceProvider class. This object is used in the decryption process.

The code then initializes the key and the initialization vector field of the RC2CryptoServiceProvider object. The RC2CryptoServiceProvider object is a wrapper to access the CSP implementation of the RC2 algorithm.

The code also calls the CreateDecryptor method. The CreateDecryptor method creates a symmetric decryptor object by using the current key and the current initialization vector.

Finally, the TransformFinalBlock method of the ICryptoTransform class does the decryption by giving the value of the input parameter as encrypted string and by giving the length of the encrypted string. After the TransformFinalBlock method has completed, you receive a message box that indicates whether the decryption process has succeeded. If the decryption process has succeeded, the program writes the decrypted string in the output file.

back to the top

Instructions to run the code
See the &quot;Code for encryption and for decryption&quot; section for information about how to download and then save the program files to the C:\ folder on your computer.

Encrypt program
<ol> Open the EncryptGroup project group in Visual Basic 6.0. To do this, double-click the EncryptGroup.vbg file. The EncryptGroup.vbg file is located in the C:\CryptographySample\EncryptInVB6 folder.</li> On the Run menu in Visual Basic 6.0, click Start With Full Compile. A Windows Form that is named Form1 appears. Form1 is the user interface for the Encrypt program.</li> <li>In the Enter full path\filename for a file to encrypt box, type the path of the file that you want to encrypt. To use the sample file that is included with the Encrypt program, type the following:

c:\CryptographySample\input.txt

</li> <li>Press TAB. The name of the file where the encrypted string will be stored appears in the Name and location of encrypted file box.

Note In this example, the path of the encrypted file is C:\CryptographySample\Input.enc.</li> <li>Click Encrypt. The Encrypt Files message box appears.</li> <li>Click OK.</li> <li>Click Exit to quit the application.</li></ol>

The encrypted string appears in the C:\CryptographySample\Input.enc file.

back to the top

DecryptInVBNET program
<ol> <li>Open the DecryptInVBNET solution in Microsoft Visual Studio .NET 2002. To do this, double-click the DecryptInVBNET.sln file. The DecryptInVBNET.sln file is located in the C:\CryptographySample\DecryptInVBNET folder.

Note If you are using Microsoft Visual Studio .NET 2003 or Microsoft Visual Studio 2005, you receive a dialog box that prompts you to upgrade the project and the solution to Microsoft Visual Studio .NET 2003 or Microsoft Visual Studio 2005. Click Yes.</li> <li>On the Debug menu in Visual Studio .NET or in Visual Studio 2005, click Start. A Windows Form that is named Form1 appears. Form1 is the user interface for the DecryptInVBNET program.</li> <li>In the Enter full path\filename for a file to decrypt box, type the path of the file that you want to decrypt. To use the sample file that is included with the DecryptInVBNET program, type the following:

c:\CryptographySample\input.enc

</li> <li>Press TAB. The name of the file where the decrypted string will be stored appears in the Name and location of decrypted file box.

Note In this example, the path of the decrypted file is C:\CryptographySample\Input.dec.</li> <li>Click Decrypt. The DecryptInVBNET message box appears.</li> <li>Click OK.</li> <li>Click Exit to quit the application.</li></ol>

The decrypted string appears in the C:\CryptographySample\Input.dec file.

back to the top

<div class="references_section">