Skip to content

Commit 08c40e8

Browse files
authored
PR #604: Move the Password property from DeflaterOutputStream into ZipOutputStream
* Move the Password property from DeflaterOutputStream into ZipOutputStream * Move cryptoTransform setup machinery from DeflatorOutputStream to ZipOutputStream * remove duplicate setup of _aesRnd
1 parent 232d690 commit 08c40e8

File tree

2 files changed

+68
-61
lines changed

2 files changed

+68
-61
lines changed

src/ICSharpCode.SharpZipLib/Zip/Compression/Streams/DeflaterOutputStream.cs

Lines changed: 4 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -153,37 +153,15 @@ public bool CanPatchEntries
153153

154154
#region Encryption
155155

156-
private string password;
157-
158-
private ICryptoTransform cryptoTransform_;
159-
160156
/// <summary>
161-
/// Returns the 10 byte AUTH CODE to be appended immediately following the AES data stream.
157+
/// The CryptoTransform currently being used to encrypt the compressed data.
162158
/// </summary>
163-
protected byte[] AESAuthCode;
159+
protected ICryptoTransform cryptoTransform_;
164160

165161
/// <summary>
166-
/// Get/set the password used for encryption.
162+
/// Returns the 10 byte AUTH CODE to be appended immediately following the AES data stream.
167163
/// </summary>
168-
/// <remarks>When set to null or if the password is empty no encryption is performed</remarks>
169-
public string Password
170-
{
171-
get
172-
{
173-
return password;
174-
}
175-
set
176-
{
177-
if ((value != null) && (value.Length == 0))
178-
{
179-
password = null;
180-
}
181-
else
182-
{
183-
password = value;
184-
}
185-
}
186-
}
164+
protected byte[] AESAuthCode;
187165

188166
/// <summary>
189167
/// Encrypt a block of data
@@ -202,34 +180,6 @@ protected void EncryptBlock(byte[] buffer, int offset, int length)
202180
cryptoTransform_.TransformBlock(buffer, 0, length, buffer, 0);
203181
}
204182

205-
/// <summary>
206-
/// Initializes encryption keys based on given <paramref name="password"/>.
207-
/// </summary>
208-
/// <param name="password">The password.</param>
209-
protected void InitializePassword(string password)
210-
{
211-
var pkManaged = new PkzipClassicManaged();
212-
byte[] key = PkzipClassic.GenerateKeys(ZipStrings.ConvertToArray(password));
213-
cryptoTransform_ = pkManaged.CreateEncryptor(key, null);
214-
}
215-
216-
/// <summary>
217-
/// Initializes encryption keys based on given password.
218-
/// </summary>
219-
protected void InitializeAESPassword(ZipEntry entry, string rawPassword,
220-
out byte[] salt, out byte[] pwdVerifier)
221-
{
222-
salt = new byte[entry.AESSaltLen];
223-
// Salt needs to be cryptographically random, and unique per file
224-
if (_aesRnd == null)
225-
_aesRnd = RandomNumberGenerator.Create();
226-
_aesRnd.GetBytes(salt);
227-
int blockSize = entry.AESKeySize / 8; // bits to bytes
228-
229-
cryptoTransform_ = new ZipAESTransform(rawPassword, salt, blockSize, true);
230-
pwdVerifier = ((ZipAESTransform)cryptoTransform_).PwdVerifier;
231-
}
232-
233183
#endregion Encryption
234184

235185
#region Deflation Support
@@ -484,12 +434,5 @@ public override void Write(byte[] buffer, int offset, int count)
484434
private bool isClosed_;
485435

486436
#endregion Instance Fields
487-
488-
#region Static Fields
489-
490-
// Static to help ensure that multiple files within a zip will get different random salt
491-
private static RandomNumberGenerator _aesRnd = RandomNumberGenerator.Create();
492-
493-
#endregion Static Fields
494437
}
495438
}

src/ICSharpCode.SharpZipLib/Zip/ZipOutputStream.cs

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using ICSharpCode.SharpZipLib.Checksum;
22
using ICSharpCode.SharpZipLib.Core;
3+
using ICSharpCode.SharpZipLib.Encryption;
34
using ICSharpCode.SharpZipLib.Zip.Compression;
45
using ICSharpCode.SharpZipLib.Zip.Compression.Streams;
56
using System;
@@ -154,6 +155,29 @@ public UseZip64 UseZip64
154155
/// </summary>
155156
public INameTransform NameTransform { get; set; } = new PathTransformer();
156157

158+
/// <summary>
159+
/// Get/set the password used for encryption.
160+
/// </summary>
161+
/// <remarks>When set to null or if the password is empty no encryption is performed</remarks>
162+
public string Password
163+
{
164+
get
165+
{
166+
return password;
167+
}
168+
set
169+
{
170+
if ((value != null) && (value.Length == 0))
171+
{
172+
password = null;
173+
}
174+
else
175+
{
176+
password = value;
177+
}
178+
}
179+
}
180+
157181
/// <summary>
158182
/// Write an unsigned short in little endian byte order.
159183
/// </summary>
@@ -634,6 +658,34 @@ public void CloseEntry()
634658
curEntry = null;
635659
}
636660

661+
/// <summary>
662+
/// Initializes encryption keys based on given <paramref name="password"/>.
663+
/// </summary>
664+
/// <param name="password">The password.</param>
665+
private void InitializePassword(string password)
666+
{
667+
var pkManaged = new PkzipClassicManaged();
668+
byte[] key = PkzipClassic.GenerateKeys(ZipStrings.ConvertToArray(password));
669+
cryptoTransform_ = pkManaged.CreateEncryptor(key, null);
670+
}
671+
672+
/// <summary>
673+
/// Initializes encryption keys based on given password.
674+
/// </summary>
675+
private void InitializeAESPassword(ZipEntry entry, string rawPassword,
676+
out byte[] salt, out byte[] pwdVerifier)
677+
{
678+
salt = new byte[entry.AESSaltLen];
679+
680+
// Salt needs to be cryptographically random, and unique per file
681+
_aesRnd.GetBytes(salt);
682+
683+
int blockSize = entry.AESKeySize / 8; // bits to bytes
684+
685+
cryptoTransform_ = new ZipAESTransform(rawPassword, salt, blockSize, true);
686+
pwdVerifier = ((ZipAESTransform)cryptoTransform_).PwdVerifier;
687+
}
688+
637689
private void WriteEncryptionHeader(long crcValue)
638690
{
639691
offset += ZipConstants.CryptoHeaderSize;
@@ -1010,6 +1062,18 @@ public override void Flush()
10101062
// NOTE: Setting the size for entries before they are added is the best solution!
10111063
private UseZip64 useZip64_ = UseZip64.Dynamic;
10121064

1065+
/// <summary>
1066+
/// The password to use when encrypting archive entries.
1067+
/// </summary>
1068+
private string password;
1069+
10131070
#endregion Instance Fields
1071+
1072+
#region Static Fields
1073+
1074+
// Static to help ensure that multiple files within a zip will get different random salt
1075+
private static RandomNumberGenerator _aesRnd = RandomNumberGenerator.Create();
1076+
1077+
#endregion Static Fields
10141078
}
10151079
}

0 commit comments

Comments
 (0)