Click here to Skip to main content
Licence CPOL
First Posted 8 Jun 2011
Views 7,452
Downloads 548
Bookmarked 19 times

How to use CryptoAPI the easy way

By | 8 Jun 2011 | Article
Use of Crypto API to encode/decode a plain text with 3DES 112.

Introduction

The Cryptography API ,also called CryptoAPI, makes it really easy to cipher and decipher files. Unfortunately, the examples found on the internet or in MSDN are often quite complex or not working properly. This program will try to show the use of CryptoAPI on the simplest example, namely on a small plain text saved in ASCII format. The cipher used is of symmetrical bloc type, called triple DES 112, with maximum 128bits key length.

The cipher is symmetrical as it needs the same key for encryption and decryption, and is a bloc cipher based on 64 bit blocs of information. It means that only multiples of 8 bytes data can be encoded, but in reality, we do not really care as CryptoAPI will make the padding automatically for us when the data is less than 8 bytes long.

Normally, in industrial code, an Initialization Vector is randomly generated at runtime, and is added at the beginning of the plain text to make cryptanalysis harder. Indeed a weakness of the cipher used in this program is that the same plain text always results in the same encrypted text. But for the purpose of this example, we will not introduce any Initialization Vector.

For the purpose of simplicity, we also ignore the use of passwords or salts to hash keys.

Originally, the code was compiled on x64 but should work well on x86 without the slightest modification. It still has to be confirmed.

Using the code

Two modules are included in the project, namely CryptoAPI to cipher plain text, and DecryptoAPI to decipher it. Both modules do not include any GUI, they simply ask the user through common dialogs to specify an input and an output file.

Once the plain text is encoded, we do not simply put it in the output file; first, it will be converted to hex values as they are easy to handle. For example, imagine the exchange of information between two people. The encrypted text could also be afterwards encoded in Base64, but it is out of scope here.

To compile with VS:

nmake /f "CryptoAPI.mak"

The code

After having requested from the user to select an input and an output file, we read the input and make our first call to CryptoAPI in order to talk with the Crypto Service Provider. Before obtaining the handle to the CSP, we first deallocate it! It might seem weird to start this way, but it proves actually useful when the program crashes and doed not deallocate memory correctly! This way at least we make sure we do a proper start by getting a handle to the CSP on the first try.

CryptAcquireContext(&hCryptProv, "CryptoAPI", NULL, PROV_DH_SCHANNEL, CRYPT_DELETEKEYSET);
if(hCryptProv)CryptReleaseContext(hCryptProv, 0);

Once this is done, we again call the same function, but this time with the option CRYPT_NEWKEYSET.

if(!CryptAcquireContext(&hCryptProv, "CryptoAPI", NULL, PROV_DH_SCHANNEL, CRYPT_NEWKEYSET))

Then we import the key from the BLOB array (refer to the source) and we make our first call to the CryptEncrypt function. By passing the fifth parameter as NULL, we are able to get the buffer size for encryption. Remember, we must supply to the CSP a multiple of the bloc length for the encryption to work properly! So we retrieve the correct length of our buffer and that's it!

Another call to CryptEncrypt, this time with our buffer padded to the right length, will give us the encoded text as output.

Before leaving, we still have to convert the output buffer into hex values. This is simply done by using the formal parameter %#.2x of the well known wsprintf function.

wsprintf(temp, "%#.2x", EncryptBuffer[index] & 0xff);

That's it for the encryption routine.

For the decryption, we quite have the same steps. First convert the hex back to ASCII, then decrypt using the API call CryptDecrypt.

That's it for the code. Enjoy.

History

First release.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Vincent Roch VR

Engineer

Germany Germany

Member

I am a reverse engineer and developer for around 10 years, mostly in C/C++, assembly. I am mainly interested in system / low-level programming.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
GeneralThanks and... Pinmemberlolydobs14:07 7 May '12  
QuestionYes, now it's really easy Pinmemberosy5:53 22 Jun '11  
GeneralMy vote of 2 PinmemberNirfoo0:24 12 Jun '11  
GeneralMy vote of 2 PinmemberJohann Gerell20:40 8 Jun '11  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web02 | 2.5.120517.1 | Last Updated 8 Jun 2011
Article Copyright 2011 by Vincent Roch VR
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid