Examples > Combine encryption and compression |
Here are is an example for Visual C++ and C# that demonstrates combining encryption and compression entirely in memory in a single pass. It shows how to use the Rijndael algorithm and the GZip compression format to encrypt compressed data and, then reverse the process.
// This code uses the #import directive. The components don't have a DLL-API. // Import the COM interface of Xceed Encryption for COM/ActiveX #import "XceedCry.dll" no_namespace named_guids /* Both Xceed Encryption for COM/ActiveX and Xceed Streaming Compression for COM/ActiveX component define an interface called IXceedProcessData that allow the components to exchange data. When using both components at the same time, this will cause a naming conflict with the compiler. To solve, that, we will instruct the second component that is imported to exclude the interface to avoid the conflict. */ // Import the COM interface of Xceed Streaming Compression for COM/ActiveX #import "XceedSco.dll" no_namespace named_guids exclude("IXceedProcessData") void CompressEncrypt1() { CoInitialize( NULL ); try { // Create and license a streaming compression control object IXceedStreamingCompressionPtr compression; compression.CreateInstance( CLSID_XceedStreamingCompression ); compression->License( _bstr_t( YourStreamingCompressionLicenseKey ) ); // Create and setup a GZip compression object IXceedGZipCompressionFormatPtr gzip; gzip.CreateInstance( CLSID_XceedGZipCompressionFormat ); // Create and license an encryption control object IXceedEncryptionPtr encryption; encryption.CreateInstance( CLSID_XceedEncryption ); encryption->License( _bstr_t( YourEncryptionLicenseKey ) ); // Create and setup a rijndael (AES) encryption object IXceedRijndaelEncryptionMethodPtr rijndael; rijndael.CreateInstance( CLSID_XceedRijndaelEncryptionMethod ); rijndael->SetSecretKeyFromPassPhrase( "This is a weak pass phrase!", 128 ); /* Order is important. We want to compress data before we encrypt it. So we will assign the compression as a sub processor to the encryption. This will have the effect that the encryption will ask the compression object to process the data BEFORE it encrypts. */ // Link the encryption object with the compression object rijndael->SubProcessing = IXceedProcessDataPtr( gzip ); // Assign the encryption object to the encryption control so we can perform operations on it encryption->EncryptionMethod = IXceedEncryptDataPtr( rijndael ); // Set up data to compress/encrypt const char * pszSource = "This is the data to encrypt"; DWORD dwSourceSize = lstrlenA( pszSource ) + 1; // Let's say we want to encrypt the null-char too // Setup variables to receive the encrypted data BYTE * pcEncrypted = NULL; DWORD dwEncryptedSize = 0; // Compress/encrypt the data encryption->Encrypt( ( BYTE* ) pszSource, dwSourceSize, TRUE, &pcEncrypted, &dwEncryptedSize ); /* TODO: Store the encrypted data somewhere */ BYTE * dataStore = new BYTE[ dwEncryptedSize ]; memcpy( dataStore, pcEncrypted, dwEncryptedSize ); // It is important to release the memory used by the encrypted data to avoid memory leaks CoTaskMemFree( pcEncrypted ); /* .... */ /* To decrypt/decompress, we setup the objects exactly like you would for compression/encryption. But we will use the Decrypt() method instead. The method will perform SubProcessing by decrypting FIRST, and then sending the data for decompression. */ // Setup variables to receive the decrypted data BYTE* pcDecrypted = NULL; DWORD dwDecryptedSize = 0; // Decrypt/decompress the data encryption->Decrypt( ( BYTE* ) dataStore, dwEncryptedSize, TRUE, &pcDecrypted, &dwDecryptedSize ); // Reconstitute the original data char * pszReconstitutedSource = ( char * ) pcDecrypted; // Release the memory used by the decrypted data CoTaskMemFree( pcDecrypted ); // Release the data store memory we used delete[] dataStore; } catch( const _com_error& xErr ) { WCHAR szMsg[50]; wsprintf( szMsg, L"Error %08x\n", xErr.Error() ); OutputDebugString( szMsg ); } catch( ... ) { OutputDebugString( L"Unknown error" ); } CoUninitialize(); }
using XceedEncryptionLib; using XceedStreamingCompressionLib; namespace CSharpExamples { public class CompressEncrypt1 { public static void Example() { bool licensed; // Create and license a streaming compression control object XceedStreamingCompression compression = new XceedStreamingCompressionClass(); licensed = compression.License( CSharpExamples.YourStreamingCompressionLicenseKey ); // Create and setup a GZip compression object XceedGZipCompressionFormat gzip = new XceedGZipCompressionFormatClass(); // Create and license an encryption control object XceedEncryption encryption = new XceedEncryptionClass(); licensed = encryption.License( CSharpExamples.YourEncryptionLicenseKey ); // Create and setup a rijndael (AES) encryption object XceedRijndaelEncryptionMethod rijndael = new XceedRijndaelEncryptionMethodClass(); rijndael.SetSecretKeyFromPassPhrase( "This is a weak pass phrase!", 128 ); /* Order is important. We want to compress data before we encrypt it. So we will assign the compression as a sub processor to the encryption. This will have the effect that the encryption will ask the compression object to process the data BEFORE it encrypts. */ // Link the encryption object with the compression object rijndael.SubProcessing = ( XceedEncryptionLib.IXceedProcessData ) gzip; // Assign the encryption object to the encryption control so we can perform operations on it encryption.EncryptionMethod = ( IXceedEncryptData ) rijndael; // Set up data to compress/encrypt string source = "This is the data to encrypt"; byte[] sourceBytes = Encoding.UTF8.GetBytes( source ); object sourceObject = sourceBytes; // Setup variables to receive the encrypted data object encryptedObject = null; // Compress/encrypt the data encryptedObject = encryption.Encrypt( ref sourceObject, true ); /* TODO: Store the encrypted data somewhere */ byte[] encryptedBytes = ( byte[] ) encryptedObject; /* .... */ /* To decrypt/decompress, we setup the objects exactly like you would for compression/encryption. But we will use the Decrypt() method instead. The method will perform SubProcessing by decrypting FIRST, and then sending the data for decompression. */ // Setup variables to receive the decrypted data encryptedObject = encryptedBytes; object decryptedObject; // Decrypt/decompress the data decryptedObject = encryption.Decrypt( ref encryptedObject, true ); // Reconstitute the original data byte[] decryptedBytes = ( byte[] ) decryptedObject; string reconstitutedSource = Encoding.UTF8.GetString( decryptedBytes ); } } }