123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219 |
- #if !NET_1_1 && !NETCF_2_0
- using System;
- using System.Security.Cryptography;
- namespace CommonMPQ.SharpZipLib.Encryption {
-
-
-
- internal class ZipAESTransform : ICryptoTransform {
- private const int PWD_VER_LENGTH = 2;
-
- private const int KEY_ROUNDS = 1000;
-
-
-
- private const int ENCRYPT_BLOCK = 16;
- private int _blockSize;
- private ICryptoTransform _encryptor;
- private readonly byte[] _counterNonce;
- private byte[] _encryptBuffer;
- private int _encrPos;
- private byte[] _pwdVerifier;
- private HMACSHA1 _hmacsha1;
- private bool _finalised;
- private bool _writeMode;
-
-
-
-
-
-
-
-
-
- public ZipAESTransform(string key, byte[] saltBytes, int blockSize, bool writeMode) {
- if (blockSize != 16 && blockSize != 32)
- throw new Exception("Invalid blocksize " + blockSize + ". Must be 16 or 32.");
- if (saltBytes.Length != blockSize / 2)
- throw new Exception("Invalid salt len. Must be " + blockSize / 2 + " for blocksize " + blockSize);
-
- _blockSize = blockSize;
- _encryptBuffer = new byte[_blockSize];
- _encrPos = ENCRYPT_BLOCK;
-
- Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(key, saltBytes, KEY_ROUNDS);
- RijndaelManaged rm = new RijndaelManaged();
- rm.Mode = CipherMode.ECB;
- _counterNonce = new byte[_blockSize];
- byte[] byteKey1 = pdb.GetBytes(_blockSize);
- byte[] byteKey2 = pdb.GetBytes(_blockSize);
- _encryptor = rm.CreateEncryptor(byteKey1, byteKey2);
- _pwdVerifier = pdb.GetBytes(PWD_VER_LENGTH);
-
- _hmacsha1 = new HMACSHA1(byteKey2);
- _writeMode = writeMode;
- }
-
-
-
- public int TransformBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) {
-
-
- if (!_writeMode) {
- _hmacsha1.TransformBlock(inputBuffer, inputOffset, inputCount, inputBuffer, inputOffset);
- }
-
- int ix = 0;
- while (ix < inputCount) {
- if (_encrPos == ENCRYPT_BLOCK) {
-
- int j = 0;
- while (++_counterNonce[j] == 0) {
- ++j;
- }
-
- _encryptor.TransformBlock(_counterNonce, 0, _blockSize, _encryptBuffer, 0);
- _encrPos = 0;
- }
- outputBuffer[ix + outputOffset] = (byte)(inputBuffer[ix + inputOffset] ^ _encryptBuffer[_encrPos++]);
-
- ix++;
- }
- if (_writeMode) {
-
- _hmacsha1.TransformBlock(outputBuffer, outputOffset, inputCount, outputBuffer, outputOffset);
- }
- return inputCount;
- }
-
-
-
- public byte[] PwdVerifier {
- get {
- return _pwdVerifier;
- }
- }
-
-
-
- public byte[] GetAuthCode() {
-
- if (!_finalised) {
- byte[] dummy = new byte[0];
- _hmacsha1.TransformFinalBlock(dummy, 0, 0);
- _finalised = true;
- }
- return _hmacsha1.Hash;
- }
- #region ICryptoTransform Members
-
-
-
- public byte[] TransformFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount) {
- throw new NotImplementedException("ZipAESTransform.TransformFinalBlock");
- }
-
-
-
- public int InputBlockSize {
- get {
- return _blockSize;
- }
- }
-
-
-
- public int OutputBlockSize {
- get {
- return _blockSize;
- }
- }
-
-
-
- public bool CanTransformMultipleBlocks {
- get {
- return true;
- }
- }
-
-
-
- public bool CanReuseTransform {
- get {
- return true;
- }
- }
-
-
-
- public void Dispose() {
- _encryptor.Dispose();
- }
- #endregion
- }
- }
- #endif
|