Xceed Encryption Library Documentation
Examples / Combine encryption and compression





In This Topic
    Combine encryption and compression
    In This Topic

    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