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

In This Topic
    AES Encryption
    In This Topic

    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 );
      }
    }
        Public Sub EncryptExample()
          Dim zipFile As AbstractFile = New DiskFile("ZipFile.zip")
    
          ' If the zip file already exists
          If zipFile.Exists Then
            ' Delete it
            zipFile.Delete()
          End If
    
          Dim zip As 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. 
          Dim password As String = "MyPassword"
    
          zip.DefaultEncryptionMethod = EncryptionMethod.WinZipAes
          zip.DefaultEncryptionStrength = 256
          zip.DefaultEncryptionPassword = password
    
          Using batch As New AutoBatchUpdate(zip)
            Dim sourceFolder As AbstractFolder = New DiskFolder("D:\Temp\foo")
    
            ' Zip the contents of the source folder
            sourceFolder.CopyFilesTo(zip, True, True)
          End Using
        End Sub

    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;
        Public Sub DecryptExample()
          ' Setup a zip file
          Dim zipFile As AbstractFile = New DiskFile("ZipFile.zip")
    
          ' If the zip file doesn't exist
          If (Not zipFile.Exists) Then
            ' Fail
            Return
          End If
    
          ' Setup a destination folder
          Dim destinationFolder As AbstractFolder = New DiskFolder("D:\Temp\Unzip")
    
          Dim zip As 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
          Me.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 = Me.m_passwords(0)
    
          ' Subscribe to the events that will allow us to handle invalid passwords
          Dim events As New ZipEvents()
          AddHandler events.ItemProgression, AddressOf OnItemProgression
          AddHandler events.ItemException, AddressOf OnItemException
    
          ' Unzip the contents of the zip archive to the destination folder
          zip.CopyFilesTo(events, zip, destinationFolder, True, True)
        End Sub
    
        Private Sub OnItemProgression(ByVal sender As Object, ByVal e As ItemProgressionEventArgs)
          ' We're about to process a new item 
    
          ' Reset the password index
          Me.m_passwordIndex = 0
        End Sub
    
        Private Sub OnItemException(ByVal sender As Object, ByVal e As ItemExceptionEventArgs)
          Dim badPassword As Boolean = False
    
          ' Get the archive object we passed through the user data
          Dim zip As ZipArchive = CType(e.UserData, ZipArchive)
    
          ' We will try to ascertain if we have an invalid password 
    
          Dim invalidDecryptionPasswordException As InvalidDecryptionPasswordException
          Dim fileSystemIOException As FileSystemIOException
    
          invalidDecryptionPasswordException = TryCast(e.Exception, InvalidDecryptionPasswordException)
          fileSystemIOException = TryCast(e.Exception, FileSystemIOException)
    
          ' If the exception says that a bad password was supplied
          If invalidDecryptionPasswordException IsNot Nothing Then
            badPassword = True
          ' If we had an I/O error during decryption
          ElseIf fileSystemIOException IsNot Nothing Then
            Dim zippedFile As ZippedFile = TryCast(e.CurrentItem, ZippedFile)
    
            ' If we were reading from a zipped file encrypted in the 'compatible' method
            If zippedFile IsNot Nothing AndAlso zippedFile.Encrypted AndAlso zippedFile.EncryptionMethod.Equals(EncryptionMethod.Compatible) Then
    '           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
            End If
          End If
    
          ' If we had a bad password
          If badPassword Then
            ' If we haven't gone through our password list
            If Me.m_passwordIndex < Me.m_passwords.Length Then
              ' Set the current password and move the index to the next password
              zip.DefaultDecryptionPassword = Me.m_passwords(Me.m_passwordIndex)
              Me.m_passwordIndex += 1
    
              ' Retry unzipping the file
              e.Action = ItemExceptionAction.Retry
            Else
              ' Skip the file
              e.Action = ItemExceptionAction.Ignore
            End If
          End If
        End Sub
    
        Private m_passwords() As String
        Private m_passwordIndex As Integer