This article makes use of the Crypto++ library, available here. To run compile the demo code, you will need to download the Windows version of the Crypto++ library and source files.
I suggest you read the Readme.txt file (found in the zip file) which contains a very good explanation on Debugging this DLL, along with source notes.
Overview
This was put together because I wanted to implement the file stream encryption (Crypto++ Library v3.2) from a Context Menu.
From a File (Context Menu)
From a Folder (Context Menu)
Implementation Notes
Because I was en/decrypting files, I needed to preserve the attributes of the file(s)... and check if the file was created ok (this was necessary because if the file was not created (e.g.: Wrong PassPhrase), I didn't want to try and set the attributes back to what the original file was).
void CFileProcess::SetAttributes(CString csFilename, BYTE btAttrib)
{
char* pFileName = csFilename.GetBuffer(csFilename.GetLength() + 1);
CFileStatus status;
status.m_mtime = 0;
status.m_attribute = btAttrib;
CFile::SetStatus( pFileName, status );
}
BYTE CFileProcess::GetAttributes(CString csFilename)
{
char* pFileName = csFilename.GetBuffer(csFilename.GetLength() + 1);
CFileStatus status;
CFile::GetStatus( pFileName, status );
return status.m_attribute;
}
BOOL CFileProcess::DoesFileExist(CString csFilename)
{
char* pFileName = csFilename.GetBuffer(csFilename.GetLength() + 1);
CFileStatus status;
return (CFile::GetStatus( pFileName, status ));
}
I also didn't want the user to encrypt files in the Windows directory, so I look into the registry (via Robert Pittenger's CRegistry class) and find the SystemRoot
entry and check it against the input file path.
I also created a function to recursive through the directories and en/decrypt the files...
void CFileProcess::FindDirFiles(CString csDirPath)
{
WIN32_FIND_DATA wfd;
HANDLE hFind;
CString csText = _T("");
if (csDirPath.Right(1) != "\\")
csDirPath += _T("\\");
csText = csDirPath + _T("*");
hFind = FindFirstFile(csText, &wfd);
if (hFind != INVALID_HANDLE_VALUE) {
do {
if ((strcmp(wfd.cFileName,_T("."))) &&
(strcmp(wfd.cFileName,_T(".."))) &&
(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
CString csDirIn = _T("");
csDirIn = csDirPath + wfd.cFileName;
FindDirFiles(csDirIn);
}
} while (FindNextFile(hFind, &wfd));
FindClose(hFind);
}
csText = csDirPath + _T("*.*");
hFind = FindFirstFile(csText, &wfd);
if (hFind != INVALID_HANDLE_VALUE) {
do {
if ((wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) {
CString csIn = _T("");
CString csOut = _T("");
csIn = csDirPath + wfd.cFileName;
if (!pThreadInfo->bEncrypt) {
csOut = csIn.Left(csIn.GetLength() - 4);
}
else {
csOut = csIn + ".enf";
}
m_csFileArrayIn.Add(csIn);
m_csFileArrayOut.Add(csOut);
}
} while (FindNextFile(hFind, &wfd));
FindClose(hFind);
}
}
That's it!
Obtaining the Crypto++ Library
The simplest way to compile the demo application, having downloaded the Crypto++ files, is to provide the compiler with the paths needed to find the header files and the compiled library. You can set these up using the Tools | Options | Directories page from the VC IDE.
Download Crypto++ v3.2
Acknowledgements
Along with the Crypto++ library (see above), the demo was done by using a very good Explorer Context Menu Example written by Smaller Animals Software Copyright 1999, All Rights Reserved and this program may be freely distributed (see About Box and included Zip). This example has been included in the demo download (zipped).
The demo makes use of Robert Pittenger's CRegistry class and Chris Maunder's CHyperlink class (both classes have been included in the demo download).
Other Articles using Crypto++ v3.2
- CLogIt by Daniel Madden.
- Coming Soon..."MFCCryptLib" (it's the Crypto++ demo (found in the Zip) with an MFC interface).
I have been programming (as a hobby) for 20+ years (Unix C, Scripting, VB, C/C++, C#). I am getting too old to talk about it and been in the Security line of work (both Military/Civilian) for 25+ years.