Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 34 additions & 1 deletion src/ICSharpCode.SharpZipLib/Zip/FastZip.cs
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,15 @@ public string Password
set { password_ = value; }
}

/// <summary>
/// Get / set the method of encrypting entries.
/// </summary>
/// <remarks>
/// Only applies when <see cref="Password"/> is set.
/// Defaults to ZipCrypto for backwards compatibility purposes.
/// </remarks>
public ZipEncryptionMethod EntryEncryptionMethod { get; set; } = ZipEncryptionMethod.ZipCrypto;

/// <summary>
/// Get or set the <see cref="INameTransform"></see> active when creating Zip files.
/// </summary>
Expand Down Expand Up @@ -369,7 +378,7 @@ public void CreateZip(Stream outputStream, string sourceDirectory, bool recurse,
{
outputStream_.SetLevel((int)CompressionLevel);

if (password_ != null)
if (false == string.IsNullOrEmpty(password_) && EntryEncryptionMethod != ZipEncryptionMethod.None)
{
outputStream_.Password = password_;
}
Expand Down Expand Up @@ -539,6 +548,10 @@ private void ProcessFile(object sender, ScanEventArgs e)
using (FileStream stream = File.Open(e.Name, FileMode.Open, FileAccess.Read, FileShare.Read))
{
ZipEntry entry = entryFactory_.MakeFileEntry(e.Name);

// Set up AES encryption for the entry if required.
ConfigureEntryEncryption(entry);

outputStream_.PutNextEntry(entry);
AddFileContents(e.Name, stream);
}
Expand All @@ -558,6 +571,26 @@ private void ProcessFile(object sender, ScanEventArgs e)
}
}

// Set up the encryption method to use for the specific entry.
private void ConfigureEntryEncryption(ZipEntry entry)
{
// Only alter the entries options if AES isn't already enabled for it
// (it might have been set up by the entry factory, and if so we let that take precedence)
if (!string.IsNullOrEmpty(Password) && entry.AESEncryptionStrength == 0)
{
switch (EntryEncryptionMethod)
{
case ZipEncryptionMethod.AES128:
entry.AESKeySize = 128;
break;

case ZipEncryptionMethod.AES256:
entry.AESKeySize = 256;
break;
}
}
}

private void AddFileContents(string name, Stream stream)
{
if (stream == null)
Expand Down
28 changes: 28 additions & 0 deletions src/ICSharpCode.SharpZipLib/Zip/ZipEncryptionMethod.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
namespace ICSharpCode.SharpZipLib.Zip
{
/// <summary>
/// The method of encrypting entries when creating zip archives.
/// </summary>
public enum ZipEncryptionMethod
{
/// <summary>
/// No encryption will be used.
/// </summary>
None,

/// <summary>
/// Encrypt entries with ZipCrypto.
/// </summary>
ZipCrypto,

/// <summary>
/// Encrypt entries with AES 128.
/// </summary>
AES128,

/// <summary>
/// Encrypt entries with AES 256.
/// </summary>
AES256
}
}
27 changes: 24 additions & 3 deletions test/ICSharpCode.SharpZipLib.Tests/Zip/FastZipHandling.cs
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,11 @@ public void ContentEqualAfterAfterArchived([Values(0, 1, 64)]int contentSize)
}

[Test]
[TestCase(ZipEncryptionMethod.ZipCrypto)]
[TestCase(ZipEncryptionMethod.AES128)]
[TestCase(ZipEncryptionMethod.AES256)]
[Category("Zip")]
public void Encryption()
public void Encryption(ZipEncryptionMethod encryptionMethod)
{
const string tempName1 = "a.dat";

Expand All @@ -174,8 +177,11 @@ public void Encryption()

try
{
var fastZip = new FastZip();
fastZip.Password = "Ahoy";
var fastZip = new FastZip
{
Password = "Ahoy",
EntryEncryptionMethod = encryptionMethod
};

fastZip.CreateZip(target, tempFilePath, false, @"a\.dat", null);

Expand All @@ -189,6 +195,21 @@ public void Encryption()
Assert.AreEqual(1, entry.Size);
Assert.IsTrue(zf.TestArchive(true));
Assert.IsTrue(entry.IsCrypted);

switch (encryptionMethod)
{
case ZipEncryptionMethod.ZipCrypto:
Assert.That(entry.AESKeySize, Is.Zero, "AES key size should be 0 for ZipCrypto encrypted entries");
break;

case ZipEncryptionMethod.AES128:
Assert.That(entry.AESKeySize, Is.EqualTo(128), "AES key size should be 128 for AES128 encrypted entries");
break;

case ZipEncryptionMethod.AES256:
Assert.That(entry.AESKeySize, Is.EqualTo(256), "AES key size should be 256 for AES256 encrypted entries");
break;
}
}
}
finally
Expand Down