WinzipAesEncryptionData.cs 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. #if !NO_CRYPTO
  2. using System;
  3. using System.Security.Cryptography;
  4. using SharpCompress.Converters;
  5. namespace SharpCompress.Common.Zip
  6. {
  7. internal class WinzipAesEncryptionData
  8. {
  9. private const int RFC2898_ITERATIONS = 1000;
  10. private readonly byte[] _salt;
  11. private readonly WinzipAesKeySize _keySize;
  12. private readonly byte[] _passwordVerifyValue;
  13. private readonly string _password;
  14. private byte[] _generatedVerifyValue;
  15. internal WinzipAesEncryptionData(WinzipAesKeySize keySize, byte[] salt, byte[] passwordVerifyValue,
  16. string password)
  17. {
  18. this._keySize = keySize;
  19. this._salt = salt;
  20. this._passwordVerifyValue = passwordVerifyValue;
  21. this._password = password;
  22. Initialize();
  23. }
  24. internal byte[] IvBytes
  25. {
  26. get; set;
  27. }
  28. internal byte[] KeyBytes
  29. {
  30. get; set;
  31. }
  32. private int KeySizeInBytes
  33. {
  34. get { return KeyLengthInBytes(_keySize);
  35. }
  36. }
  37. internal static int KeyLengthInBytes(WinzipAesKeySize keySize)
  38. {
  39. switch (keySize)
  40. {
  41. case WinzipAesKeySize.KeySize128:
  42. return 16;
  43. case WinzipAesKeySize.KeySize192:
  44. return 24;
  45. case WinzipAesKeySize.KeySize256:
  46. return 32;
  47. }
  48. throw new InvalidOperationException();
  49. }
  50. private void Initialize()
  51. {
  52. var rfc2898 = new Rfc2898DeriveBytes(_password, _salt, RFC2898_ITERATIONS);
  53. KeyBytes = rfc2898.GetBytes(KeySizeInBytes); // 16 or 24 or 32 ???
  54. IvBytes = rfc2898.GetBytes(KeySizeInBytes);
  55. _generatedVerifyValue = rfc2898.GetBytes(2);
  56. short verify = DataConverter.LittleEndian.GetInt16(_passwordVerifyValue, 0);
  57. if (_password != null)
  58. {
  59. short generated = DataConverter.LittleEndian.GetInt16(_generatedVerifyValue, 0);
  60. if (verify != generated)
  61. {
  62. throw new InvalidFormatException("bad password");
  63. }
  64. }
  65. }
  66. }
  67. }
  68. #endif