12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879 |
- #if !NO_CRYPTO
- 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");
- }
- }
- }
- }
- }
- #endif
|