Skip to content

Comprehensive File Security SDK

Track file change, control file access in real time, transparent file encryption

Menu
  • Home
  • Solutions
  • Download
  • Contact

File Encryption In C++

File encryption is the process of converting data in a file into a secret code to protect the data. It is a security measure that ensures that only authorized users can access the data in the file. Encryption is used to protect sensitive information such as personal data, financial information, and confidential business data from unauthorized access . Encrypt file in C++ is complex, the EEFD SDK provides a complete modular framework for the developers to build the file encryption software.

Types of Cryptography: There are two types of cryptography:

  • Symmetric Cryptography: It is an encryption system where the sender and receiver of a message use a single common key to encrypt and decrypt messages. Symmetric Key Systems are faster and simpler, but the sender and receiver have to somehow exchange keys securely. The most popular symmetric-key cryptography system is Data Encryption System(DES).
  • Asymmetric Cryptography: Under this system, a pair of keys is used to encrypt and decrypt information. A public key is used for encryption and a private key is used for decryption. The public key and the private key are different. Even if the public key is known by everyone, the intended receiver can only decode it because he alone knows the private key.

To encrypt file with C++, there are many C++ encryption libraries available for the programming. Some of the popular ones include:

  1. Crypto++ Library: A free C++ class library of cryptographic schemes that contains the following algorithms: AES, DES, 3DES, Blowfish, Twofish, Serpent, IDEA, RC2, RC5, RC6, CAST-256, Camellia, SEED, Skipjack, SHACAL-2, Tiger, Whirlpool, RIPEMD, MD2, MD4, MD5, SHA-1, SHA-2, SHA-3, Keccak, Skein, and BLAKE2. 
  2. Aes256: A library written in C++ that offers AES 256 bit encryption and decryption. It uses a salt to extend the encryption key to 256 bit. The encrypted stream is aware of this salt and of the padding added to complete the last encryption block
  3. OpenSSL: A software library for applications that provide secure communications over computer networks against eavesdropping or need to identify the party at the other end. It supports the ciphers: AES, Blowfish, Camellia, Chacha20, Poly1305, SEED, CAST-128, DES, IDEA, RC2, RC4, RC5, Triple DES, GOST 28147-89,SM4.
  4. Botan: A cryptography toolkit that aims to be the best option for cryptography in C++ by offering the tools necessary to implement a range of practical systems, such as TLS protocol, X.509 certificates, modern AEAD ciphers, PKCS#11 and TPM hardware support, password hashing, and post quantum crypto schemes
  5. CNG: A Cryptography API has been released since Windows Vista. The Next Generation (CNG) is a cryptographic API that you can use to create encryption security software for encryption key management, cryptography and data security, and cryptography and network security. CNG allows you to encrypt data by using a minimum number of function calls and allows you to perform all of the memory management. While many of the protocol implementation details are left up to the user, CNG provides the primitives that perform the actual data encryption and decryption tasks. CNG is validated to Federal Information Processing Standards (FIPS) 140-2 and is part of the Target of Evaluation for the Windows Common Criteria certification.

The C++ Auto Encryption Code Snippet with EEFD

Even though there are a lot of C++ encryption libraries available in the market, but it is still very complex to encrypt file in C++. The EEFD is a mature commercial encryption SDK. It provides a complete modular framework for the developers even without much encryption development experience to build the on-access file encryption software within a day.

EaseFilter Encryption Filter Driver (EEFD) is a file system encryption filter driver. It provides a comprehensive security solution to develop the transparent on-access file level encryption products. The EEFD allows you to encrypt the newly created files transparently. You can authorize the on-access encryption/decryption under the control of client-defined policy. 

The below code snippet demonstrates how to setup a filter rule to encrypt the file transparently in an encryption folder with EEFD SDK, only the authorized processes and users can read the encrypted file, the unauthorized processes or users will get the raw encrypted data.


DWORD	threadCount = 5;
DWORD   connectionTimeout = 20; //SECONDS

FilterControl* filterControl = FilterControl::GetSingleInstance();

FileFilterRule fileFilterRule(L"c:\\encryptFolder\\*");
fileFilterRule.AccessFlag = ALLOW_MAX_RIGHT_ACCESS|ENABLE_FILE_ENCRYPTION_RULE;	

//if you have a master key, you can set it here, or if you want to get the encryption key from the callback function then don't set the key here.
//256 bit,32bytes encrytpion key
unsigned char key[] = {0x60,0x3d,0xeb,0x10,0x15,0xca,0x71,0xbe,0x2b,0x73,0xae,0xf0,0x85,0x7d,0x77,0x81,0x1f,0x35,0x2c,0x07,0x3b,0x61,0x08,0xd7,0x2d,0x98,0x10,0xa3,0x09,0x14,0xdf,0xf4};
if(!fileFilterRule.set_EncryptionKey(key,sizeof(key)))
{
	goto Exit;
}

//get raw encrypted data access rights.
ULONG rawEncryptionRights = accessFlag & (~ALLOW_READ_ENCRYPTED_FILES);
//disable the explorer to read encrypted file, explorer will get the raw encrypted data.
//so you can copy the encrypted file to other place in Windows explorer, the file will be kept encrypted. 
//this feature requires the process filter driver feature, it need to enable the process filter driver.
ULONG filterType = FILE_SYSTEM_ENCRYPTION|FILE_SYSTEM_PROCESS;
fileFilterRule.AddAccessRightsToProcessName(L"explorer.exe", rawEncryptionRights);

filterControl->AddFileFilter(fileFilterRule);
filterControl->StartFilter(filterType,threadCount,connectionTimeout,registerKey);

_tprintf(_T("\n\nStart Encryption for folder %ws,\r\nThe new created file will be encrypted, the encrypted file can be decrypted automatically in this folder\
	.\r\n Press any key to stop the filter driver.\n"),fileFilterMask);

system("pause");
getchar();

filterControl->StopFilter();
delete filterControl;

C++ Encrypting Data Example With CNG

The following example shows how to encrypt data with CNG by using the advanced encryption standard (AES) symmetric encryption algorithm.

#include windows.h
#include stdio.h
#include bcrypt.h

#define NT_SUCCESS(Status)          (((NTSTATUS)(Status)) >= 0)

#define STATUS_UNSUCCESSFUL         ((NTSTATUS)0xC0000001L)


#define DATA_TO_ENCRYPT  "Test Data"


const BYTE rgbPlaintext[] = 
{
    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 
    0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
};

static const BYTE rgbIV[] =
{
    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
    0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
};

static const BYTE rgbAES128Key[] =
{
    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 
    0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
};

void PrintBytes(
                IN BYTE     *pbPrintData,
                IN DWORD    cbDataLen)
{
    DWORD dwCount = 0;

    for(dwCount=0; dwCount < cbDataLen;dwCount++) { printf("0x%02x, ",pbPrintData[dwCount]); if(0 == (dwCount + 1 )%10) putchar('\n'); } } void __cdecl wmain( int argc, __in_ecount(argc) LPWSTR *wargv) { BCRYPT_ALG_HANDLE hAesAlg = NULL; BCRYPT_KEY_HANDLE hKey = NULL; NTSTATUS status = STATUS_UNSUCCESSFUL; DWORD cbCipherText = 0, cbPlainText = 0, cbData = 0, cbKeyObject = 0, cbBlockLen = 0, cbBlob = 0; PBYTE pbCipherText = NULL, pbPlainText = NULL, pbKeyObject = NULL, pbIV = NULL, pbBlob = NULL; UNREFERENCED_PARAMETER(argc); UNREFERENCED_PARAMETER(wargv); // Open an algorithm handle. if(!NT_SUCCESS(status = BCryptOpenAlgorithmProvider( &hAesAlg, BCRYPT_AES_ALGORITHM, NULL, 0))) { wprintf(L"**** Error 0x%x returned by BCryptOpenAlgorithmProvider\n", status); goto Cleanup; } // Calculate the size of the buffer to hold the KeyObject. if(!NT_SUCCESS(status = BCryptGetProperty( hAesAlg, BCRYPT_OBJECT_LENGTH, (PBYTE)&cbKeyObject, sizeof(DWORD), &cbData, 0))) { wprintf(L"**** Error 0x%x returned by BCryptGetProperty\n", status); goto Cleanup; } // Allocate the key object on the heap. pbKeyObject = (PBYTE)HeapAlloc (GetProcessHeap (), 0, cbKeyObject); if(NULL == pbKeyObject) { wprintf(L"**** memory allocation failed\n"); goto Cleanup; } // Calculate the block length for the IV. if(!NT_SUCCESS(status = BCryptGetProperty( hAesAlg, BCRYPT_BLOCK_LENGTH, (PBYTE)&cbBlockLen, sizeof(DWORD), &cbData, 0))) { wprintf(L"**** Error 0x%x returned by BCryptGetProperty\n", status); goto Cleanup; } // Determine whether the cbBlockLen is not longer than the IV length. if (cbBlockLen > sizeof (rgbIV))
    {
        wprintf (L"**** block length is longer than the provided IV length\n");
        goto Cleanup;
    }

    // Allocate a buffer for the IV. The buffer is consumed during the 
    // encrypt/decrypt process.
    pbIV= (PBYTE) HeapAlloc (GetProcessHeap (), 0, cbBlockLen);
    if(NULL == pbIV)
    {
        wprintf(L"**** memory allocation failed\n");
        goto Cleanup;
    }

    memcpy(pbIV, rgbIV, cbBlockLen);

    if(!NT_SUCCESS(status = BCryptSetProperty(
                                hAesAlg, 
                                BCRYPT_CHAINING_MODE, 
                                (PBYTE)BCRYPT_CHAIN_MODE_CBC, 
                                sizeof(BCRYPT_CHAIN_MODE_CBC), 
                                0)))
    {
        wprintf(L"**** Error 0x%x returned by BCryptSetProperty\n", status);
        goto Cleanup;
    }

                

     // Generate the key from supplied input key bytes.
    if(!NT_SUCCESS(status = BCryptGenerateSymmetricKey(
                                        hAesAlg, 
                                        &hKey, 
                                        pbKeyObject, 
                                        cbKeyObject, 
                                        (PBYTE)rgbAES128Key, 
                                        sizeof(rgbAES128Key), 
                                        0)))
    {
        wprintf(L"**** Error 0x%x returned by BCryptGenerateSymmetricKey\n", status);
        goto Cleanup;
    }

  
    // Save another copy of the key for later.
    if(!NT_SUCCESS(status = BCryptExportKey(
                                        hKey,
                                        NULL,
                                        BCRYPT_OPAQUE_KEY_BLOB,
                                        NULL,
                                        0,
                                        &cbBlob,
                                        0)))
    {
        wprintf(L"**** Error 0x%x returned by BCryptExportKey\n", status);
        goto Cleanup;
    }


    // Allocate the buffer to hold the BLOB.
    pbBlob = (PBYTE)HeapAlloc (GetProcessHeap (), 0, cbBlob);
    if(NULL == pbBlob)
    {
        wprintf(L"**** memory allocation failed\n");
        goto Cleanup;
    }

    if(!NT_SUCCESS(status = BCryptExportKey(
                                        hKey, 
                                        NULL, 
                                        BCRYPT_OPAQUE_KEY_BLOB,
                                        pbBlob, 
                                        cbBlob, 
                                        &cbBlob, 
                                        0)))
    {
        wprintf(L"**** Error 0x%x returned by BCryptExportKey\n", status);
        goto Cleanup;
    }
 
    cbPlainText = sizeof(rgbPlaintext);
    pbPlainText = (PBYTE)HeapAlloc (GetProcessHeap (), 0, cbPlainText);
    if(NULL == pbPlainText)
    {
        wprintf(L"**** memory allocation failed\n");
        goto Cleanup;
    }

    memcpy(pbPlainText, rgbPlaintext, sizeof(rgbPlaintext));
    
    //
    // Get the output buffer size.
    //
    if(!NT_SUCCESS(status = BCryptEncrypt(
                                        hKey, 
                                        pbPlainText, 
                                        cbPlainText,
                                        NULL,
                                        pbIV,
                                        cbBlockLen,
                                        NULL, 
                                        0, 
                                        &cbCipherText, 
                                        BCRYPT_BLOCK_PADDING)))
    {
        wprintf(L"**** Error 0x%x returned by BCryptEncrypt\n", status);
        goto Cleanup;
    }

    pbCipherText = (PBYTE)HeapAlloc (GetProcessHeap (), 0, cbCipherText);
    if(NULL == pbCipherText)
    {
        wprintf(L"**** memory allocation failed\n");
        goto Cleanup;
    }

    // Use the key to encrypt the plaintext buffer.
    // For block sized messages, block padding will add an extra block.
    if(!NT_SUCCESS(status = BCryptEncrypt(
                                        hKey, 
                                        pbPlainText, 
                                        cbPlainText,
                                        NULL,
                                        pbIV,
                                        cbBlockLen, 
                                        pbCipherText, 
                                        cbCipherText, 
                                        &cbData, 
                                        BCRYPT_BLOCK_PADDING)))
    {
        wprintf(L"**** Error 0x%x returned by BCryptEncrypt\n", status);
        goto Cleanup;
    }

    // Destroy the key and reimport from saved BLOB.
    if(!NT_SUCCESS(status = BCryptDestroyKey(hKey)))
    {
        wprintf(L"**** Error 0x%x returned by BCryptDestroyKey\n", status);
        goto Cleanup;
    }    
    hKey = 0;

    if(pbPlainText)
    {
        HeapFree(GetProcessHeap(), 0, pbPlainText);
    }

    pbPlainText = NULL;

    // We can reuse the key object.
    memset(pbKeyObject, 0 , cbKeyObject);

    
    // Reinitialize the IV because encryption would have modified it.
    memcpy(pbIV, rgbIV, cbBlockLen);


    if(!NT_SUCCESS(status = BCryptImportKey(
                                        hAesAlg,
                                        NULL,
                                        BCRYPT_OPAQUE_KEY_BLOB,
                                        &hKey,
                                        pbKeyObject,
                                        cbKeyObject,
                                        pbBlob,
                                        cbBlob,
                                        0)))
    {
        wprintf(L"**** Error 0x%x returned by BCryptGenerateSymmetricKey\n", status);
        goto Cleanup;
    }
       

    //
    // Get the output buffer size.
    //
    if(!NT_SUCCESS(status = BCryptDecrypt(
                                    hKey, 
                                    pbCipherText, 
                                    cbCipherText, 
                                    NULL,
                                    pbIV,
                                    cbBlockLen,
                                    NULL, 
                                    0, 
                                    &cbPlainText, 
                                    BCRYPT_BLOCK_PADDING)))
    {
        wprintf(L"**** Error 0x%x returned by BCryptDecrypt\n", status);
        goto Cleanup;
    }

    pbPlainText = (PBYTE)HeapAlloc (GetProcessHeap (), 0, cbPlainText);
    if(NULL == pbPlainText)
    {
        wprintf(L"**** memory allocation failed\n");
        goto Cleanup;
    }

    if(!NT_SUCCESS(status = BCryptDecrypt(
                                    hKey, 
                                    pbCipherText, 
                                    cbCipherText, 
                                    NULL,
                                    pbIV, 
                                    cbBlockLen,
                                    pbPlainText, 
                                    cbPlainText, 
                                    &cbPlainText, 
                                    BCRYPT_BLOCK_PADDING)))
    {
        wprintf(L"**** Error 0x%x returned by BCryptDecrypt\n", status);
        goto Cleanup;
    }


    if (0 != memcmp(pbPlainText, (PBYTE)rgbPlaintext, sizeof(rgbPlaintext))) 
    {
        wprintf(L"Expected decrypted text comparison failed.\n");
        goto Cleanup;
    } 

    wprintf(L"Success!\n");


Cleanup:

    if(hAesAlg)
    {
        BCryptCloseAlgorithmProvider(hAesAlg,0);
    }

    if (hKey)    
    {
        BCryptDestroyKey(hKey);
    }

    if(pbCipherText)
    {
        HeapFree(GetProcessHeap(), 0, pbCipherText);
    }

    if(pbPlainText)
    {
        HeapFree(GetProcessHeap(), 0, pbPlainText);
    }

    if(pbKeyObject)
    {
        HeapFree(GetProcessHeap(), 0, pbKeyObject);
    }

    if(pbIV)
    {
        HeapFree(GetProcessHeap(), 0, pbIV);
    }

}

Recent Posts

  • File Security Filter Driver SDK

  • Using File System Filter Driver SDK

  • EEFD Transparent File Encryption SDK

  • EaseFilter File Access Control SDK

  • EaseFilter File Access Monitor SDK

  • Secure Sandbox Tool

  • Folder Locker Tool

  • Secure File Sharing with DRM

  • Process Control SDK

  • Registry Protection SDK

  • Process Monitor SDK

  • File Access Control Lists

  • Authentication and Authorization

  • Zero Trust File Access Security

  • Blacklisting and Whitelisting

  • Network File Monitor and Protector

  • Block File Access to USB Drive

  • Setup The Trusted Process Rights

  • Encrypt File With Header

  • Encrypt File On the Go

  • Track File Change In Application

File Knowledge Base

  • Understand File I/O
  • Understand File Encryption
  • Understand Filter Driver
  • Filter Driver Framework
  • Isolation Filter Driver
  • Filter Driver Resources
  • Storage Tiering Filter Driver

File Encryption

  • Understand File Encryption
  • Understand AES Encryption
  • File Encryption In C#
  • File Encryption In C++
  • Symmetric Encryption
  • Asymmetric Encryption
  • Digital Signature
  • EEFD透明文件加密開發包
  • EaseFilter文件監控開發包
  • EaseFilter文件訪問控制開發包

Comprehensive File Security SDK 2023 . Powered by WordPress