protected abstract BlockCipher DecryptBlock(BlockCipher block);
public virtual void Encrypt(Stream inStream, Stream outStream, byte[] key) { BinaryWriter binaryWriter = (BinaryWriter)null; BinaryReader binaryReader = (BinaryReader)null; this.Key = key; int position = (int)outStream.Position; int length = (int)inStream.Length; int capacity = length + this.pBlockSizeValue / 8 + 4; if (capacity % (this.pBlockSizeValue / 8) != 0) { capacity += this.pBlockSizeValue / 8 - capacity % (this.pBlockSizeValue / 8); } MemoryStream memoryStream = new MemoryStream(capacity); try { memoryStream.SetLength((long)capacity); binaryWriter = new BinaryWriter((Stream)memoryStream, this.Encoding); binaryReader = new BinaryReader(inStream, this.Encoding); binaryWriter.Write(new RNDGenerator().GetBytes(this.pBlockSizeValue / 8)); binaryWriter.Write(length); binaryWriter.Write(binaryReader.ReadBytes(length)); binaryReader = new BinaryReader((Stream)memoryStream, this.Encoding); binaryWriter = new BinaryWriter(outStream, this.Encoding); BlockCipher block1 = new BlockCipher(this.pBlockSizeValue); if (this.CipherMode == CipherMode.CBC || this.CipherMode == CipherMode.CFB) { if (this.pIVValue == null) { this.pIVValue = this.GenerateIV(); } for (int index = 0; index < block1.Length && index < this.pIVValue.Length; ++index) { block1[index] = this.pIVValue[index]; } } memoryStream.Seek(0L, SeekOrigin.Begin); outStream.Seek((long)position, SeekOrigin.Begin); while (memoryStream.Position < memoryStream.Length) { switch (this.CipherMode) { case CipherMode.CBC: BlockCipher blockCipher1 = this.EncryptBlock(new BlockCipher(binaryReader.ReadBytes(this.pBlockSizeValue / 8)) ^ block1); block1 = blockCipher1; binaryWriter.Write((byte[])blockCipher1); continue; case CipherMode.ECB: BlockCipher blockCipher2 = this.EncryptBlock(new BlockCipher(binaryReader.ReadBytes(this.pBlockSizeValue / 8))); binaryWriter.Write((byte[])blockCipher2); continue; case CipherMode.OFB: block1 = this.EncryptBlock(block1); BlockCipher blockCipher3 = new BlockCipher(binaryReader.ReadBytes(this.pBlockSizeValue / 8)) ^ block1; block1 = blockCipher3; binaryWriter.Write((byte[])blockCipher3); continue; case CipherMode.CFB: block1 = this.EncryptBlock(block1); BlockCipher blockCipher4 = new BlockCipher(binaryReader.ReadBytes(this.pBlockSizeValue / 8)) ^ block1; block1 = blockCipher4; binaryWriter.Write((byte[])blockCipher4); continue; case CipherMode.CTS: BlockCipher block2 = new BlockCipher(binaryReader.ReadBytes(this.pBlockSizeValue / 8)); BlockCipher blockCipher5; if (outStream.Position + (long)(this.pBlockSizeValue / 8 * 2) >= outStream.Length) { blockCipher5 = this.EncryptBlock(block2); } else { blockCipher5 = this.EncryptBlock(block2 ^ block1); block1 = blockCipher5; } binaryWriter.Write((byte[])blockCipher5); continue; default: throw new NotSupportedException("Cann't support the special CipherMode."); } } } catch (Exception ex) { throw ex; } finally { binaryReader?.Close(); binaryWriter?.Flush(); memoryStream?.Flush(); } GC.Collect(); }
public virtual void Decrypt(Stream inStream, Stream outStream, byte[] key) { MemoryStream memoryStream = (MemoryStream)null; BinaryWriter binaryWriter = (BinaryWriter)null; BinaryReader binaryReader = (BinaryReader)null; this.Key = key; int length = (int)inStream.Length; try { memoryStream = new MemoryStream(length); binaryWriter = new BinaryWriter((Stream)memoryStream); binaryReader = new BinaryReader(inStream, this.Encoding); BlockCipher block1 = new BlockCipher(this.pBlockSizeValue); BlockCipher block2; while (inStream.Position < inStream.Length) { switch (this.CipherMode) { case CipherMode.CBC: block2 = new BlockCipher(binaryReader.ReadBytes(this.pBlockSizeValue / 8)); BlockCipher blockCipher1 = (BlockCipher)block2.Clone(); block2 = this.DecryptBlock(block2); block2 ^= block1; block1 = blockCipher1; binaryWriter.Write((byte[])block2); continue; case CipherMode.ECB: block2 = new BlockCipher(binaryReader.ReadBytes(this.pBlockSizeValue / 8)); block2 = this.DecryptBlock(block2); binaryWriter.Write((byte[])block2); continue; case CipherMode.OFB: block2 = new BlockCipher(binaryReader.ReadBytes(this.pBlockSizeValue / 8)); BlockCipher blockCipher2 = this.EncryptBlock(block1); BlockCipher blockCipher3 = (BlockCipher)block2.Clone(); block2 ^= blockCipher2; block1 = blockCipher3; binaryWriter.Write((byte[])block2); continue; case CipherMode.CFB: block2 = new BlockCipher(binaryReader.ReadBytes(this.pBlockSizeValue / 8)); BlockCipher blockCipher4 = this.EncryptBlock(block1); BlockCipher blockCipher5 = (BlockCipher)block2.Clone(); block2 ^= blockCipher4; block1 = blockCipher5; binaryWriter.Write((byte[])block2); continue; case CipherMode.CTS: block2 = new BlockCipher(binaryReader.ReadBytes(this.pBlockSizeValue / 8)); if (outStream.Position + (long)(this.pBlockSizeValue / 8 * 2) >= outStream.Length) { block2 = this.DecryptBlock(block2); } else { BlockCipher blockCipher6 = (BlockCipher)block2.Clone(); block2 = this.DecryptBlock(block2); block2 ^= block1; block1 = blockCipher6; } binaryWriter.Write((byte[])block2); continue; default: throw new NotSupportedException("Cann't support the special CipherMode."); } } binaryReader = new BinaryReader((Stream)memoryStream, this.Encoding); binaryWriter = new BinaryWriter(outStream, this.Encoding); memoryStream.Seek((long)(this.pBlockSizeValue / 8), SeekOrigin.Begin); int count = binaryReader.ReadInt32(); binaryWriter.Write(binaryReader.ReadBytes(count)); } finally { binaryReader?.Close(); binaryWriter?.Flush(); memoryStream?.Flush(); } GC.Collect(); }