TripleDesCipher
Implements 3DES cipher algorithm.
using Org.BouncyCastle.Crypto.Paddings;
using Renci.SshNet.Common;
using Renci.SshNet.Security.Cryptography.Ciphers.Modes;
using System;
using System.Security.Cryptography;
namespace Renci.SshNet.Security.Cryptography.Ciphers
{
public sealed class TripleDesCipher : BlockCipher, IDisposable
{
private sealed class BclImpl : BlockCipher, IDisposable
{
private readonly TripleDES _des;
private readonly ICryptoTransform _encryptor;
private readonly ICryptoTransform _decryptor;
public BclImpl(byte[] key, byte[] iv, System.Security.Cryptography.CipherMode mode, PaddingMode padding)
: base(key, 8, null, null)
{
TripleDES tripleDES = TripleDES.Create();
tripleDES.FeedbackSize = 64;
tripleDES.Key = base.Key;
tripleDES.IV = iv.Take(8);
tripleDES.Mode = mode;
tripleDES.Padding = padding;
_des = tripleDES;
_encryptor = _des.CreateEncryptor();
_decryptor = _des.CreateDecryptor();
}
public override byte[] Encrypt(byte[] input, int offset, int length)
{
if (_des.Padding != PaddingMode.None)
return _encryptor.TransformFinalBlock(input, offset, length);
int num = 0;
if (length % (int)base.BlockSize > 0) {
System.Security.Cryptography.CipherMode mode = _des.Mode;
if (((uint)(mode - 3) <= 1) ? true : false) {
num = base.BlockSize - length % (int)base.BlockSize;
input = input.Take(offset, length);
length += num;
Array.Resize(ref input, length);
offset = 0;
}
}
byte[] array = new byte[length];
_encryptor.TransformBlock(input, offset, length, array, 0);
if (num > 0)
Array.Resize(ref array, array.Length - num);
return array;
}
public override byte[] Decrypt(byte[] input, int offset, int length)
{
if (_des.Padding != PaddingMode.None)
return _decryptor.TransformFinalBlock(input, offset, length);
int num = 0;
if (length % (int)base.BlockSize > 0) {
System.Security.Cryptography.CipherMode mode = _des.Mode;
if (((uint)(mode - 3) <= 1) ? true : false) {
num = base.BlockSize - length % (int)base.BlockSize;
input = input.Take(offset, length);
length += num;
Array.Resize(ref input, length);
offset = 0;
}
}
byte[] array = new byte[length];
_decryptor.TransformBlock(input, offset, length, array, 0);
if (num > 0)
Array.Resize(ref array, array.Length - num);
return array;
}
public override int EncryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
{
throw new NotImplementedException("Invalid usage of EncryptBlock.");
}
public override int DecryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
{
throw new NotImplementedException("Invalid usage of DecryptBlock.");
}
public void Dispose()
{
_des.Dispose();
_encryptor.Dispose();
_decryptor.Dispose();
}
}
private sealed class BlockImpl : BlockCipher, IDisposable
{
private readonly TripleDES _tripleDES;
private readonly ICryptoTransform _encryptor;
private readonly ICryptoTransform _decryptor;
public BlockImpl(byte[] key, CipherMode mode, IBlockCipherPadding padding)
: base(key, 8, mode, padding)
{
TripleDES tripleDES = TripleDES.Create();
tripleDES.Key = key;
tripleDES.Mode = System.Security.Cryptography.CipherMode.ECB;
tripleDES.Padding = PaddingMode.None;
_tripleDES = tripleDES;
_encryptor = tripleDES.CreateEncryptor();
_decryptor = tripleDES.CreateDecryptor();
}
public override int EncryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
{
return _encryptor.TransformBlock(inputBuffer, inputOffset, inputCount, outputBuffer, outputOffset);
}
public override int DecryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
{
return _decryptor.TransformBlock(inputBuffer, inputOffset, inputCount, outputBuffer, outputOffset);
}
public void Dispose()
{
_tripleDES.Dispose();
_encryptor.Dispose();
_decryptor.Dispose();
}
}
private readonly BlockCipher _impl;
public TripleDesCipher(byte[] key, byte[] iv, System.Security.Cryptography.CipherMode mode, bool pkcs7Padding)
: base(key, 8, null, null)
{
if (mode == System.Security.Cryptography.CipherMode.CFB)
_impl = new BlockImpl(key, new CfbCipherMode(iv), pkcs7Padding ? new Pkcs7Padding() : null);
else
_impl = new BclImpl(key, iv, mode, (!pkcs7Padding) ? PaddingMode.None : PaddingMode.PKCS7);
}
public override byte[] Encrypt(byte[] input, int offset, int length)
{
return _impl.Encrypt(input, offset, length);
}
public override byte[] Decrypt(byte[] input, int offset, int length)
{
return _impl.Decrypt(input, offset, length);
}
public override int EncryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
{
return _impl.EncryptBlock(inputBuffer, inputOffset, inputCount, outputBuffer, outputOffset);
}
public override int DecryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
{
return _impl.DecryptBlock(inputBuffer, inputOffset, inputCount, outputBuffer, outputOffset);
}
public void Dispose()
{
(_impl as IDisposable)?.Dispose();
}
}
}