Skip to content

Commit 59e3080

Browse files
authored
PR #380: Add support for AES encryption in FastZip.CreateZip
1 parent cfc5112 commit 59e3080

File tree

3 files changed

+86
-4
lines changed

3 files changed

+86
-4
lines changed

src/ICSharpCode.SharpZipLib/Zip/FastZip.cs

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,15 @@ public string Password
226226
set { password_ = value; }
227227
}
228228

229+
/// <summary>
230+
/// Get / set the method of encrypting entries.
231+
/// </summary>
232+
/// <remarks>
233+
/// Only applies when <see cref="Password"/> is set.
234+
/// Defaults to ZipCrypto for backwards compatibility purposes.
235+
/// </remarks>
236+
public ZipEncryptionMethod EntryEncryptionMethod { get; set; } = ZipEncryptionMethod.ZipCrypto;
237+
229238
/// <summary>
230239
/// Get or set the <see cref="INameTransform"></see> active when creating Zip files.
231240
/// </summary>
@@ -428,7 +437,7 @@ private void CreateZip(Stream outputStream, string sourceDirectory, bool recurse
428437
outputStream_.IsStreamOwner = !leaveOpen;
429438
outputStream_.NameTransform = null; // all required transforms handled by us
430439

431-
if (password_ != null)
440+
if (false == string.IsNullOrEmpty(password_) && EntryEncryptionMethod != ZipEncryptionMethod.None)
432441
{
433442
outputStream_.Password = password_;
434443
}
@@ -597,6 +606,10 @@ private void ProcessFile(object sender, ScanEventArgs e)
597606
using (FileStream stream = File.Open(e.Name, FileMode.Open, FileAccess.Read, FileShare.Read))
598607
{
599608
ZipEntry entry = entryFactory_.MakeFileEntry(e.Name);
609+
610+
// Set up AES encryption for the entry if required.
611+
ConfigureEntryEncryption(entry);
612+
600613
outputStream_.PutNextEntry(entry);
601614
AddFileContents(e.Name, stream);
602615
}
@@ -616,6 +629,26 @@ private void ProcessFile(object sender, ScanEventArgs e)
616629
}
617630
}
618631

632+
// Set up the encryption method to use for the specific entry.
633+
private void ConfigureEntryEncryption(ZipEntry entry)
634+
{
635+
// Only alter the entries options if AES isn't already enabled for it
636+
// (it might have been set up by the entry factory, and if so we let that take precedence)
637+
if (!string.IsNullOrEmpty(Password) && entry.AESEncryptionStrength == 0)
638+
{
639+
switch (EntryEncryptionMethod)
640+
{
641+
case ZipEncryptionMethod.AES128:
642+
entry.AESKeySize = 128;
643+
break;
644+
645+
case ZipEncryptionMethod.AES256:
646+
entry.AESKeySize = 256;
647+
break;
648+
}
649+
}
650+
}
651+
619652
private void AddFileContents(string name, Stream stream)
620653
{
621654
if (stream == null)
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
namespace ICSharpCode.SharpZipLib.Zip
2+
{
3+
/// <summary>
4+
/// The method of encrypting entries when creating zip archives.
5+
/// </summary>
6+
public enum ZipEncryptionMethod
7+
{
8+
/// <summary>
9+
/// No encryption will be used.
10+
/// </summary>
11+
None,
12+
13+
/// <summary>
14+
/// Encrypt entries with ZipCrypto.
15+
/// </summary>
16+
ZipCrypto,
17+
18+
/// <summary>
19+
/// Encrypt entries with AES 128.
20+
/// </summary>
21+
AES128,
22+
23+
/// <summary>
24+
/// Encrypt entries with AES 256.
25+
/// </summary>
26+
AES256
27+
}
28+
}

test/ICSharpCode.SharpZipLib.Tests/Zip/FastZipHandling.cs

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -159,8 +159,11 @@ public void ContentEqualAfterAfterArchived([Values(0, 1, 64)]int contentSize)
159159
}
160160

161161
[Test]
162+
[TestCase(ZipEncryptionMethod.ZipCrypto)]
163+
[TestCase(ZipEncryptionMethod.AES128)]
164+
[TestCase(ZipEncryptionMethod.AES256)]
162165
[Category("Zip")]
163-
public void Encryption()
166+
public void Encryption(ZipEncryptionMethod encryptionMethod)
164167
{
165168
const string tempName1 = "a.dat";
166169

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

175178
try
176179
{
177-
var fastZip = new FastZip();
178-
fastZip.Password = "Ahoy";
180+
var fastZip = new FastZip
181+
{
182+
Password = "Ahoy",
183+
EntryEncryptionMethod = encryptionMethod
184+
};
179185

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

@@ -189,6 +195,21 @@ public void Encryption()
189195
Assert.AreEqual(1, entry.Size);
190196
Assert.IsTrue(zf.TestArchive(true));
191197
Assert.IsTrue(entry.IsCrypted);
198+
199+
switch (encryptionMethod)
200+
{
201+
case ZipEncryptionMethod.ZipCrypto:
202+
Assert.That(entry.AESKeySize, Is.Zero, "AES key size should be 0 for ZipCrypto encrypted entries");
203+
break;
204+
205+
case ZipEncryptionMethod.AES128:
206+
Assert.That(entry.AESKeySize, Is.EqualTo(128), "AES key size should be 128 for AES128 encrypted entries");
207+
break;
208+
209+
case ZipEncryptionMethod.AES256:
210+
Assert.That(entry.AESKeySize, Is.EqualTo(256), "AES key size should be 256 for AES256 encrypted entries");
211+
break;
212+
}
192213
}
193214
}
194215
finally

0 commit comments

Comments
 (0)