How to encrypt a file using c++
Author : Ester Artieda
From TechnologicalWiki
[edit] Introduction
We know as encryption the process of transforming information (referred to as plaintext) using an cipher algorithm to make it unreadable to anyone except those possessing special knowledge, usually referred to as a key. The result of the process is encrypted information or ciphertext. This process is very interesting when we want to save or send information safetly because only if you know the key, you will get the correct data.
[edit] Code
There are a lot of encryption algorithms, some of the most usual ones are DES, Triple DES, DSA, ECDSA, RSA, Enigma, AES, ARC4... In this example we are using DES, but you can choose one of the algorithms of Wincrypt.h file.
int CDESdll::DESEncryption(char* inName, char* outName, wchar_t* pszPassword)
{
//Initialization of variables
HCRYPTPROV hProv = 0;
HCRYPTKEY hKey = 0;
HCRYPTKEY hXchgKey = 0;
HCRYPTHASH hHash = NULL;
PBYTE pbKeyBlob = NULL;
DWORD dwKeyBlobLen;
PBYTE pbBuffer = NULL;
DWORD dwBlockLen;
DWORD dwBufferLen;
DWORD dwCount;
BOOL bEOF = 0;
Open files to read and write correctly:
// open in and out files
FILE* fin;
FILE* fout;
fin=fopen(const_cast<char*>(inName),"rb+");
fout = fopen(const_cast<char*>(outName),"wb");
On CryptAcquireContext is where the type of encryption is selected
// Get a handle to the default provider.
if(!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, 0))
// Some sort of error occured, create default key container.
if (!CryptAcquireContext( &hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET))
// Error creating key container!
return -1;
To encrypt a file is necessary to have a key, in this example, if we don't introduce a key the program will take the session key like the encryption key
if(!pszPassword || !pszPassword[0])
{
//-----------------------------------------------------------
// No password was passed.
// Encrypt the file with a random session key, and write the
// key to a file.
//-----------------------------------------------------------
// Create a random session key.
if(CryptGenKey(hProv, CALG_DES, CRYPT_EXPORTABLE, &hKey))
{
_tprintf(TEXT("A session key has been created. \n"));
}
else
{
_tprintf(TEXT("A session key has NOT been created. \n"));
return -1;
}
//
// Get the handle to the exchange public key.
if(CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hXchgKey))
{
_tprintf(TEXT("The user public key has been retrieved. \n"));
}
else
{
if(NTE_NO_KEY == GetLastError())
{
// No exchange key exists. Try to create one.
if(!CryptGenKey(hProv, AT_KEYEXCHANGE, CRYPT_EXPORTABLE, &hXchgKey))
{
_tprintf(TEXT("Could not create a user public key.\n"));
return -1;
}
}
else
{
_tprintf(TEXT("User public key is not available and may not exist.\n"));
return -1;
}
}
//-----------------------------------------------------------
// Determine size of the key BLOB, and allocate memory.
if(CryptExportKey( hKey, hXchgKey, SIMPLEBLOB, 0, NULL, &dwKeyBlobLen))
{
_tprintf(TEXT("The key BLOB is %d bytes long. \n"), dwKeyBlobLen);
}
else
{
_tprintf(TEXT("Error computing BLOB length! \n"));
return -1;
}
if(pbKeyBlob = (BYTE *)malloc(dwKeyBlobLen))
{
_tprintf(TEXT("Memory is allocated for the key BLOB. \n"));
}
else
{
_tprintf(TEXT("Out of memory. \n"));
return -1;
}
//-----------------------------------------------------------
// Encrypt and export the session key into a simple key
// BLOB.
if(CryptExportKey( hKey, hXchgKey, SIMPLEBLOB, 0, pbKeyBlob, &dwKeyBlobLen))
{
_tprintf(TEXT("The key has been exported. \n"));
}
else
{
_tprintf(TEXT("Error during CryptExportKey!\n"));
return -1;
}
//-----------------------------------------------------------
// Release the key exchange key handle.
if(hXchgKey)
{
if(!(CryptDestroyKey(hXchgKey)))
{
_tprintf(TEXT("Error during CryptDestroyKey.\n"));
return -1;
}
hXchgKey = 0;
}
//-----------------------------------------------------------
// Write the size of the key BLOB to the destination file.
if(!WriteFile( outName, &dwKeyBlobLen, sizeof(DWORD), &dwCount, NULL))
{
_tprintf(TEXT("Error writing header.\n"));
return -1;
}
else
{
_tprintf(TEXT("A file header has been written. \n"));
}
//-----------------------------------------------------------
// Write the key BLOB to the destination file.
if(!WriteFile( outName, pbKeyBlob, dwKeyBlobLen, &dwCount, NULL))
{
_tprintf(TEXT("Error writing header.\n"));
return -1;
}
else
{
_tprintf(TEXT("The key BLOB has been written to the file. \n "));
}
// Free memory.
free(pbKeyBlob);
}
else
{
//-----------------------------------------------------------
// The file will be encrypted with a session key derived
// from a password.
// The session key will be recreated when the file is
// decrypted only if the password used to create the key is
// available.
//-----------------------------------------------------------
// Create a hash object.
if(CryptCreateHash( hProv, CALG_MD5, 0, 0, &hHash))
{
_tprintf(TEXT("A hash object has been created. \n"));
}
else
{
_tprintf(TEXT("Error during CryptCreateHash!\n"));
return -1;
}
//-----------------------------------------------------------
// Hash the password.
if(CryptHashData( hHash, (BYTE *)pszPassword, lstrlen(pszPassword), 0))
{
_tprintf(TEXT("The password has been added to the hash. \n"));
}
else
{
_tprintf(TEXT("Error during CryptHashData. \n"));
return -1;
}
//-----------------------------------------------------------
// Derive a session key from the hash object.
if(CryptDeriveKey( hProv, CALG_RC2, hHash, 0, &hKey))
{
_tprintf(TEXT("An encryption key is derived from the password hash. \n"));
}
else
{
_tprintf(TEXT("Error during CryptDeriveKey!\n"));
return -1;
}
}
Create a random session key
if(!pszPassword || !pszPassword[0])
{
//-----------------------------------------------------------
// No password was passed.
// Encrypt the file with a random session key, and write the
// key to a file.
//-----------------------------------------------------------
// Create a random session key.
CryptGenKey( hProv, ENCRYPT_ALGORITHM, CRYPT_EXPORTABLE, &hKey);
}else
{
CryptGetUserKey( hProv, AT_KEYEXCHANGE, &hXchgKey);
}
if(!CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hXchgKey))
{
CryptGenKey(hProv, AT_KEYEXCHANGE, CRYPT_EXPORTABLE, &hXchgKey);
}
dwBlockLen = 1000 - 1000 % ENCRYPT_BLOCK_SIZE;
if(ENCRYPT_BLOCK_SIZE > 1)
{
dwBufferLen = dwBlockLen + ENCRYPT_BLOCK_SIZE;
}
else
{
dwBufferLen = dwBlockLen;
}
pbBuffer = (PBYTE) malloc (dwBufferLen);
Write encrypted text on the out file
// write on the out file and read from the input file
do {
// Read ENCRYPT_BLOCK_SIZE bytes
dwCount = fread(pbBuffer,1,ENCRYPT_BLOCK_SIZE,fin);
if (ferror (fin))
{
printf(("Error reading Plaintext!\n"));
return -1;
}
bEOF = feof (fin);
// encrypt data
if (!CryptEncrypt (hKey, 0, bEOF, 0, pbBuffer, &dwCount, dwBufferLen))
{
printf(("bytes required:%d\n"), dwCount);
printf(("Error %x during CryptEncrypt!\n"),
GetLastError ());
return -1;
}
// write encrypted data on out file
fwrite (pbBuffer, 1, dwCount, fout);
if (ferror (fout))
{
printf(("Error writing Ciphertext!\n"));
return -1;
}
} while (!bEOF);
fclose(fin);
fclose(fout);
return 0;
}
[edit] References
http://msdn.microsoft.com/en-us/library/aa382358(VS.85).aspx


