<PackageReference Include="SSH.NET" Version="2016.0.0" />

DesCipher

public class DesCipher : BlockCipher
Implements DES cipher algorithm.
using System; namespace Renci.SshNet.Security.Cryptography.Ciphers { public class DesCipher : BlockCipher { private int[] _encryptionKey; private int[] _decryptionKey; private static readonly short[] bytebit = new short[8] { 128, 64, 32, 16, 8, 4, 2, 1 }; private static readonly int[] bigbyte = new int[24] { 8388608, 4194304, 2097152, 1048576, 524288, 262144, 131072, 65536, 32768, 16384, 8192, 4096, 2048, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1 }; private static readonly byte[] pc1 = new byte[56] { 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3 }; private static readonly byte[] totrot = new byte[16] { 1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28 }; private static readonly byte[] pc2 = new byte[48] { 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9, 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1, 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 }; private static readonly uint[] SP1 = new uint[64] { 16843776, 0, 65536, 16843780, 16842756, 66564, 4, 65536, 1024, 16843776, 16843780, 1024, 16778244, 16842756, 16777216, 4, 1028, 16778240, 16778240, 66560, 66560, 16842752, 16842752, 16778244, 65540, 16777220, 16777220, 65540, 0, 1028, 66564, 16777216, 65536, 16843780, 4, 16842752, 16843776, 16777216, 16777216, 1024, 16842756, 65536, 66560, 16777220, 1024, 4, 16778244, 66564, 16843780, 65540, 16842752, 16778244, 16777220, 1028, 66564, 16843776, 1028, 16778240, 16778240, 0, 65540, 66560, 0, 16842756 }; private static readonly uint[] SP2 = new uint[64] { 2148565024, 2147516416, 32768, 1081376, 1048576, 32, 2148532256, 2147516448, 2147483680, 2148565024, 2148564992, 2147483648, 2147516416, 1048576, 32, 2148532256, 1081344, 1048608, 2147516448, 0, 2147483648, 32768, 1081376, 2148532224, 1048608, 2147483680, 0, 1081344, 32800, 2148564992, 2148532224, 32800, 0, 1081376, 2148532256, 1048576, 2147516448, 2148532224, 2148564992, 32768, 2148532224, 2147516416, 32, 2148565024, 1081376, 32, 32768, 2147483648, 32800, 2148564992, 1048576, 2147483680, 1048608, 2147516448, 2147483680, 1048608, 1081344, 0, 2147516416, 32800, 2147483648, 2148532256, 2148565024, 1081344 }; private static readonly uint[] SP3 = new uint[64] { 520, 134349312, 0, 134348808, 134218240, 0, 131592, 134218240, 131080, 134217736, 134217736, 131072, 134349320, 131080, 134348800, 520, 134217728, 8, 134349312, 512, 131584, 134348800, 134348808, 131592, 134218248, 131584, 131072, 134218248, 8, 134349320, 512, 134217728, 134349312, 134217728, 131080, 520, 131072, 134349312, 134218240, 0, 512, 131080, 134349320, 134218240, 134217736, 512, 0, 134348808, 134218248, 131072, 134217728, 134349320, 8, 131592, 131584, 134217736, 134348800, 134218248, 520, 134348800, 131592, 8, 134348808, 131584 }; private static readonly uint[] SP4 = new uint[64] { 8396801, 8321, 8321, 128, 8396928, 8388737, 8388609, 8193, 0, 8396800, 8396800, 8396929, 129, 0, 8388736, 8388609, 1, 8192, 8388608, 8396801, 128, 8388608, 8193, 8320, 8388737, 1, 8320, 8388736, 8192, 8396928, 8396929, 129, 8388736, 8388609, 8396800, 8396929, 129, 0, 0, 8396800, 8320, 8388736, 8388737, 1, 8396801, 8321, 8321, 128, 8396929, 129, 1, 8192, 8388609, 8193, 8396928, 8388737, 8193, 8320, 8388608, 8396801, 128, 8388608, 8192, 8396928 }; private static readonly uint[] SP5 = new uint[64] { 256, 34078976, 34078720, 1107296512, 524288, 256, 1073741824, 34078720, 1074266368, 524288, 33554688, 1074266368, 1107296512, 1107820544, 524544, 1073741824, 33554432, 1074266112, 1074266112, 0, 1073742080, 1107820800, 1107820800, 33554688, 1107820544, 1073742080, 0, 1107296256, 34078976, 33554432, 1107296256, 524544, 524288, 1107296512, 256, 33554432, 1073741824, 34078720, 1107296512, 1074266368, 33554688, 1073741824, 1107820544, 34078976, 1074266368, 256, 33554432, 1107820544, 1107820800, 524544, 1107296256, 1107820800, 34078720, 0, 1074266112, 1107296256, 524544, 33554688, 1073742080, 524288, 0, 1074266112, 34078976, 1073742080 }; private static readonly uint[] SP6 = new uint[64] { 536870928, 541065216, 16384, 541081616, 541065216, 16, 541081616, 4194304, 536887296, 4210704, 4194304, 536870928, 4194320, 536887296, 536870912, 16400, 0, 4194320, 536887312, 16384, 4210688, 536887312, 16, 541065232, 541065232, 0, 4210704, 541081600, 16400, 4210688, 541081600, 536870912, 536887296, 16, 541065232, 4210688, 541081616, 4194304, 16400, 536870928, 4194304, 536887296, 536870912, 16400, 536870928, 541081616, 4210688, 541065216, 4210704, 541081600, 0, 541065232, 16, 16384, 541065216, 4210704, 16384, 4194320, 536887312, 0, 541081600, 536870912, 4194320, 536887312 }; private static readonly uint[] SP7 = new uint[64] { 2097152, 69206018, 67110914, 0, 2048, 67110914, 2099202, 69208064, 69208066, 2097152, 0, 67108866, 2, 67108864, 69206018, 2050, 67110912, 2099202, 2097154, 67110912, 67108866, 69206016, 69208064, 2097154, 69206016, 2048, 2050, 69208066, 2099200, 2, 67108864, 2099200, 67108864, 2099200, 2097152, 67110914, 67110914, 69206018, 69206018, 2, 2097154, 67108864, 67110912, 2097152, 69208064, 2050, 2099202, 69208064, 2050, 67108866, 69208066, 69206016, 2099200, 0, 2, 69208066, 0, 2099202, 69206016, 2048, 67108866, 67110912, 2048, 2097154 }; private static readonly uint[] SP8 = new uint[64] { 268439616, 4096, 262144, 268701760, 268435456, 268439616, 64, 268435456, 262208, 268697600, 268701760, 266240, 268701696, 266304, 4096, 64, 268697600, 268435520, 268439552, 4160, 266240, 262208, 268697664, 268701696, 4160, 0, 0, 268697664, 268435520, 268439552, 266304, 262144, 266304, 262144, 268701696, 4096, 64, 268697664, 4096, 266304, 268439552, 64, 268435520, 268697600, 268697664, 268435456, 262144, 268439616, 0, 268701760, 262208, 268435520, 268697600, 268439552, 268439616, 0, 268701760, 266240, 266240, 4160, 4160, 262208, 268435456, 268701696 }; public DesCipher(byte[] key, CipherMode mode, CipherPadding padding) : base(key, 8, mode, padding) { } public override int EncryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) { if (inputOffset + base.BlockSize > inputBuffer.Length) throw new IndexOutOfRangeException("input buffer too short"); if (outputOffset + base.BlockSize > outputBuffer.Length) throw new IndexOutOfRangeException("output buffer too short"); if (_encryptionKey == null) _encryptionKey = GenerateWorkingKey(true, base.Key); DesFunc(_encryptionKey, inputBuffer, inputOffset, outputBuffer, outputOffset); return base.BlockSize; } public override int DecryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) { if (inputOffset + base.BlockSize > inputBuffer.Length) throw new IndexOutOfRangeException("input buffer too short"); if (outputOffset + base.BlockSize > outputBuffer.Length) throw new IndexOutOfRangeException("output buffer too short"); if (_decryptionKey == null) _decryptionKey = GenerateWorkingKey(false, base.Key); DesFunc(_decryptionKey, inputBuffer, inputOffset, outputBuffer, outputOffset); return base.BlockSize; } protected int[] GenerateWorkingKey(bool encrypting, byte[] key) { ValidateKey(); int[] array = new int[32]; bool[] array2 = new bool[56]; bool[] array3 = new bool[56]; for (int i = 0; i < 56; i++) { int num = pc1[i]; array2[i] = ((key[(uint)num >> 3] & bytebit[num & 7]) != 0); } for (int j = 0; j < 16; j++) { int num2 = (!encrypting) ? (15 - j << 1) : (j << 1); int num3 = num2 + 1; array[num2] = (array[num3] = 0); for (int k = 0; k < 28; k++) { int num4 = k + totrot[j]; if (num4 < 28) array3[k] = array2[num4]; else array3[k] = array2[num4 - 28]; } for (int l = 28; l < 56; l++) { int num4 = l + totrot[j]; if (num4 < 56) array3[l] = array2[num4]; else array3[l] = array2[num4 - 28]; } for (int m = 0; m < 24; m++) { if (array3[pc2[m]]) array[num2] |= bigbyte[m]; if (array3[pc2[m + 24]]) array[num3] |= bigbyte[m]; } } for (int n = 0; n != 32; n += 2) { int num5 = array[n]; int num6 = array[n + 1]; array[n] = (((num5 & 16515072) << 6) | ((num5 & 4032) << 10) | (int)((uint)(num6 & 16515072) >> 10) | (int)((uint)(num6 & 4032) >> 6)); array[n + 1] = (((num5 & 258048) << 12) | ((num5 & 63) << 16) | (int)((uint)(num6 & 258048) >> 4) | (num6 & 63)); } return array; } protected virtual void ValidateKey() { int num = base.Key.Length * 8; if (num != 64) throw new ArgumentException($"""{num}"""); } protected static void DesFunc(int[] wKey, byte[] input, int inOff, byte[] outBytes, int outOff) { uint num = Cipher.BigEndianToUInt32(input, inOff); uint num2 = Cipher.BigEndianToUInt32(input, inOff + 4); uint num3 = ((num >> 4) ^ num2) & 252645135; num2 ^= num3; num ^= num3 << 4; num3 = (((num >> 16) ^ num2) & 65535); num2 ^= num3; num ^= num3 << 16; num3 = (((num2 >> 2) ^ num) & 858993459); num ^= num3; num2 ^= num3 << 2; num3 = (((num2 >> 8) ^ num) & 16711935); num ^= num3; num2 ^= num3 << 8; num2 = ((num2 << 1) | (num2 >> 31)); num3 = (uint)((int)(num ^ num2) & -1431655766); num ^= num3; num2 ^= num3; num = ((num << 1) | (num >> 31)); for (int i = 0; i < 8; i++) { num3 = ((num2 << 28) | (num2 >> 4)); num3 = (uint)((int)num3 ^ wKey[i * 4]); uint num4 = SP7[num3 & 63]; num4 |= SP5[(num3 >> 8) & 63]; num4 |= SP3[(num3 >> 16) & 63]; num4 |= SP1[(num3 >> 24) & 63]; num3 = (uint)((int)num2 ^ wKey[i * 4 + 1]); num4 |= SP8[num3 & 63]; num4 |= SP6[(num3 >> 8) & 63]; num4 |= SP4[(num3 >> 16) & 63]; num4 |= SP2[(num3 >> 24) & 63]; num ^= num4; num3 = ((num << 28) | (num >> 4)); num3 = (uint)((int)num3 ^ wKey[i * 4 + 2]); num4 = SP7[num3 & 63]; num4 |= SP5[(num3 >> 8) & 63]; num4 |= SP3[(num3 >> 16) & 63]; num4 |= SP1[(num3 >> 24) & 63]; num3 = (uint)((int)num ^ wKey[i * 4 + 3]); num4 |= SP8[num3 & 63]; num4 |= SP6[(num3 >> 8) & 63]; num4 |= SP4[(num3 >> 16) & 63]; num4 |= SP2[(num3 >> 24) & 63]; num2 ^= num4; } num2 = ((num2 << 31) | (num2 >> 1)); num3 = (uint)((int)(num ^ num2) & -1431655766); num ^= num3; num2 ^= num3; num = ((num << 31) | (num >> 1)); num3 = (((num >> 8) ^ num2) & 16711935); num2 ^= num3; num ^= num3 << 8; num3 = (((num >> 2) ^ num2) & 858993459); num2 ^= num3; num ^= num3 << 2; num3 = (((num2 >> 16) ^ num) & 65535); num ^= num3; num2 ^= num3 << 16; num3 = (((num2 >> 4) ^ num) & 252645135); num ^= num3; num2 ^= num3 << 4; Cipher.UInt32ToBigEndian(num2, outBytes, outOff); Cipher.UInt32ToBigEndian(num, outBytes, outOff + 4); } } }