Files
sharpcompress/src/SharpCompress/Common/Zip/WinzipAesEncryptionData.cs
Adam Hathcock 9540b01bcc NET Standard 1.3 and 2.0 only (#482)
* Remove NET35, NET45 and NET Standard 1.0

* Update README and memset

* Remove NETCORE build flag

* NET 46 too?

* Update packages and usage
2019-10-10 09:24:41 +01:00

77 lines
2.2 KiB
C#

using System;
using System.Security.Cryptography;
using SharpCompress.Converters;
namespace SharpCompress.Common.Zip
{
internal class WinzipAesEncryptionData
{
private const int RFC2898_ITERATIONS = 1000;
private readonly byte[] _salt;
private readonly WinzipAesKeySize _keySize;
private readonly byte[] _passwordVerifyValue;
private readonly string _password;
private byte[] _generatedVerifyValue;
internal WinzipAesEncryptionData(WinzipAesKeySize keySize, byte[] salt, byte[] passwordVerifyValue,
string password)
{
this._keySize = keySize;
this._salt = salt;
this._passwordVerifyValue = passwordVerifyValue;
this._password = password;
Initialize();
}
internal byte[] IvBytes
{
get; set;
}
internal byte[] KeyBytes
{
get; set;
}
private int KeySizeInBytes
{
get { return KeyLengthInBytes(_keySize);
}
}
internal static int KeyLengthInBytes(WinzipAesKeySize keySize)
{
switch (keySize)
{
case WinzipAesKeySize.KeySize128:
return 16;
case WinzipAesKeySize.KeySize192:
return 24;
case WinzipAesKeySize.KeySize256:
return 32;
}
throw new InvalidOperationException();
}
private void Initialize()
{
var rfc2898 = new Rfc2898DeriveBytes(_password, _salt, RFC2898_ITERATIONS);
KeyBytes = rfc2898.GetBytes(KeySizeInBytes); // 16 or 24 or 32 ???
IvBytes = rfc2898.GetBytes(KeySizeInBytes);
_generatedVerifyValue = rfc2898.GetBytes(2);
short verify = DataConverter.LittleEndian.GetInt16(_passwordVerifyValue, 0);
if (_password != null)
{
short generated = DataConverter.LittleEndian.GetInt16(_generatedVerifyValue, 0);
if (verify != generated)
{
throw new InvalidFormatException("bad password");
}
}
}
}
}