Xceed .NET Libraries Documentation
Welcome to Xceed Data Manipulation Compoents for .NET and .NET Standard / Basic Concepts / Zip and streaming capabilities / AES Encryption

    AES Encryption

    Xceed's implementation of AES encryption lets you incorporate industry standard strong encryption in your .NET applications.

    Encryption method

    The EncryptionMethod enumeration provides the following values, representing the kind of encryption used:

    Value Description
    Compatible The traditional ZIP encryption. This is a weak encryption method.
    WinZipAES The WinZip AES encryption method. This is a strong encryption method.
    Note: This encryption method is not currently available in Xceed's .NET Compact Framework products.
    You can specify the implementation to be used for AES encryption. See Using alternative AES implementations under Advanced Concepts.
    The length of the password is not limited. However, to preserve compatibility with other Zip compression utilities, it is recommended that you limit passwords to no greater than 80 characters. It is also advisable to only use ASCII characters because there is no accepted standard on how to encode non-ASCII characters in passwords.

    Encrypting

    The following code demonstrates how to use Xceed's AES encryption. WinZipAes is used as the encryption method, and the encryption strength is set to 256 bits:

    public void EncryptExample()
    {
      AbstractFile zipFile = new DiskFile( @"ZipFile.zip" );
    
      // If the zip file already exists
      if( zipFile.Exists )
      {
        // Delete it
        zipFile.Delete();
      }
    
      ZipArchive zip = new ZipArchive( zipFile );
    
      /* The length of the password is not limited. However, to preserve compatibility
      with other Zip compression utilities, it is recommended that you limit passwords
      to no greater than 80 characters.
      
      It is also advisable to only use ASCII characters because there is no
      accepted standard on how to encode non-ASCII characters in passwords. */
      string password = "MyPassword";
    
      zip.DefaultEncryptionMethod = EncryptionMethod.WinZipAes;
      zip.DefaultEncryptionStrength = 256;
      zip.DefaultEncryptionPassword = password;
    
      using( AutoBatchUpdate batch = new AutoBatchUpdate( zip ) )
      {
        AbstractFolder sourceFolder = new DiskFolder( @"D:\Temp\foo" );
    
        // Zip the contents of the source folder
        sourceFolder.CopyFilesTo( zip, true, true );
      }
    }

    Decrypting

    Decryption is demonstrated in the following code. Note that it is not necessary to specify the encryption method or strength, as these are detected automatically.

    public void DecryptExample()
    {
      // Setup a zip file
      AbstractFile zipFile = new DiskFile( @"ZipFile.zip" );
    
      // If the zip file doesn't exist
      if( !zipFile.Exists )
      {
        // Fail
        return;
      }
    
      // Setup a destination folder
      AbstractFolder destinationFolder = new DiskFolder( @"D:\Temp\Unzip" );
    
      ZipArchive zip = new ZipArchive( zipFile );
    
      /* The length of the password is not limited. However, to preserve compatibility
      with other Zip compression utilities, it is recommended that you limit passwords
      to no greater than 80 characters.
      
      It is also advisable to only use ASCII characters because there is no
      accepted standard on how to encode non-ASCII characters in passwords. */
    
      // Set up the list of password possible for the items in this archive
      this.m_passwords = new string[]
      {
        "MyPassword",
        "wrong password",
        "fkEI-969=6kei$[BbZ \"6Iq- =[",
        "}8{)zM#$k//O?t~=iG'Si{AF\"S~\'/8@1n",
      };
    
      // Use our most likely password as the default
      zip.DefaultDecryptionPassword = this.m_passwords[ 0 ];
    
      // Subscribe to the events that will allow us to handle invalid passwords
      ZipEvents events = new ZipEvents();
      events.ItemProgression += new ItemProgressionEventHandler( OnItemProgression );
      events.ItemException += new ItemExceptionEventHandler( OnItemException );
    
      // Unzip the contents of the zip archive to the destination folder
      zip.CopyFilesTo( events, zip, destinationFolder, true, true );
    }
    
    private void OnItemProgression( object sender, ItemProgressionEventArgs e )
    {
      /* We're about to process a new item */
    
      // Reset the password index
      this.m_passwordIndex = 0;
    }
    
    private void OnItemException( object sender, ItemExceptionEventArgs e )
    {
      bool badPassword = false;
    
      // Get the archive object we passed through the user data
      ZipArchive zip = ( ZipArchive ) e.UserData;
    
      /* We will try to ascertain if we have an invalid password */
    
      InvalidDecryptionPasswordException invalidDecryptionPasswordException;
      FileSystemIOException fileSystemIOException;
    
      invalidDecryptionPasswordException = e.Exception as InvalidDecryptionPasswordException;
      fileSystemIOException = e.Exception as FileSystemIOException;
    
      // If the exception says that a bad password was supplied
      if( invalidDecryptionPasswordException != null )
      {
        badPassword = true;
      }
      // If we had an I/O error during decryption
      else if( fileSystemIOException != null )
      {
        ZippedFile zippedFile = e.CurrentItem as ZippedFile;
    
        // If we were reading from a zipped file encrypted in the 'compatible' method
        if( zippedFile != null && zippedFile.Encrypted &&
            zippedFile.EncryptionMethod.Equals( EncryptionMethod.Compatible ) )
        {
          /* It's possible the I/O error occurred because the password is invalid.
          The was the 'compatible' encryption is designed doesn't provide for 100%
          accurate bad password detection, unfortunately.
            
          Note that AES encryption has no such design flaw. */
          badPassword = true;
        }
      }
    
      // If we had a bad password
      if( badPassword )
      {
        // If we haven't gone through our password list
        if( this.m_passwordIndex < this.m_passwords.Length )
        {
          // Set the current password and move the index to the next password
          zip.DefaultDecryptionPassword = this.m_passwords[ this.m_passwordIndex++ ];
    
          // Retry unzipping the file
          e.Action = ItemExceptionAction.Retry;
        }
        else
        {
          // Skip the file
          e.Action = ItemExceptionAction.Ignore;
        }
      }
    }
    
    private string[] m_passwords;
    private int m_passwordIndex;