Xceed Encryption Library Documentation
Combine encryption and compression





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 );

    }

  }

}
See Also