I had to deal with some cryptography and found not a lot of clean and understandable stuff and so I want to share my results. The GUI is designed for demonstration use, and so the passwords are visible.
Security is a problem of today: criminals, identity thefts and observation is a common news today. Everybody knows the massive observations since the horrible news of honest Edward Snowden, which looks like the Watergate scandal of our times.
I guess that Microsoft complies to US laws and so the government will have some ways to crack these encryption.
Using the Code
WinCrypto-API is used straightforward because I decided to use the most advanced Algorithm with AES 256. Who wants or needs another algorithm should learn from the MSDN. The best starting point is the startup function CryptAcquireContext.
Next comes the first pitfall. The CryptHashData is somehow tricky, because NOT EVERY algorithm is supported by every provider. And there may be also minor differences between some flavor of Windows (XP and 2003) or even Service packs.
So I have decided to encapsulate the API in a class which can be easily accessed from the outside by creating an object and providing a password. So in my class is some error handling and some cleanup code to close the used handles. To use the
Crypto-API, you need the
wincrypt-header and the library "advapi32.lib". I like the solution to include both in the implementation file, because then I am done for all configurations and I can also use the file in other projects.
#pragma comment (lib, "advapi32")
The use of my class from outside is very straightforward.
if( ca.EnCrypt( cryptedBuffer, dataLen, sizeof(cryptedBuffer) ) )
TRACE( "Encryption success");
lenEncrypted = dataLen; ctlOutput.SetWindowText(TEXT("The secret is now encrypted"));
Take care of the length of the encrypted buffer: it is needed for decryption.
Here is the decryption, which I provided in an extra function and new object.
DWORD dataLen = lenEncrypted;
if( ca2.DeCrypt( deCryptedBuffer, dataLen ) )
TRACE( "Decryption success");
memcpy( csDecrypted.GetBufferSetLength(dataLen/sizeof(TCHAR)), deCryptedBuffer, dataLen ); csDecrypted.ReleaseBuffer();
ctlOutput.SetWindowText(TEXT("Decrypted secret is: ") + csDecrypted );
For the output, I copied the buffer to
CString buffer for a useful output in my GUI.
Points of Interest
As expected, the
WinCrypto provided some huzzle. But now in understanding is it a fine way to improve security.
The security stands and falls with the password, so the best way is an individual password. And "top of the pops" is to NOT store the password anywhere. So anybody has a chance to get or guess it.
Very Important hint: The password boxes should have the password style, so the value is hidden. If have chosen normal text style to demonstrate encryption and decryption.
In a public release, the resources should be fixed. In the resource editor, it should look like this: