⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 des.cs

📁 Granados是一个基于.NET的SSH客户端库。同时支持SSH1和SSH2。实现了AES, Blowfish, TripleDES, RSA, DSA等加密验证算法。实现TCP协议连接。
💻 CS
📖 第 1 页 / 共 2 页
字号:
/* ---------------------------------------------------------------------------
 *
 * Copyright (c) Routrek Networks, Inc.    All Rights Reserved..
 * 
 * This file is a part of the Granados SSH Client Library that is subject to
 * the license included in the distributed package.
 * You may not use this file except in compliance with the license.
 * 
 * ---------------------------------------------------------------------------
 * 
 * I implemented this algorithm with reference to following products or books though the algorithm is known publicly.
 *   * MindTerm ( AppGate Network Security )
 *   * Applied Cryptography ( Bruce Schneier )
 * 
 */
using System;

namespace Routrek.Crypto
{
	public class DES
	{
		private const int BLOCK_SIZE = 8; // bytes in a data-block

		uint[] _key;
		byte[] _iv;
		byte[] _temp;

		public DES() {
			_key = new uint[32];
			_iv = new byte[8];
			_temp = new byte[8];
		}
		public void SetIV(byte[] newiv) {
			Array.Copy(newiv, 0, _iv, 0, _iv.Length);
		}
		public void SetIV(byte[] newiv, int offset) {
			Array.Copy(newiv, offset, _iv, 0, _iv.Length);
		}

		public void InitializeKey(byte[] key, int offset)
		{
			uint i, c, d, t, s, shifts;

			c = CipherUtil.GetIntLE(key, offset+0);
			d = CipherUtil.GetIntLE(key, offset+4);

			t  = ((d >> 4) ^ c)  & 0x0f0f0f0f;
			c ^= t;
			d ^= t << 4;
			t = (((c << (16 - (-2))) ^ c) & 0xcccc0000);
			c = c ^ t ^ (t >> (16 - (-2)));
			t = (((d << (16 - (-2))) ^ d) & 0xcccc0000);
			d = d ^ t ^ (t >> (16 - (-2)));
			t  = ((d >> 1) ^ c)  & 0x55555555;
			c ^= t;
			d ^= t << 1;
			t  = ((c >> 8) ^ d)  & 0x00ff00ff;
			d ^= t;
			c ^= t << 8;
			t  = ((d >> 1) ^ c)  & 0x55555555;
			c ^= t;
			d ^= t << 1;

			d  = ((d & 0xff) << 16) | (d & 0xff00) |
				((d >> 16) & 0xff) | ((c >> 4) & 0xf000000);
			c &= 0x0fffffff;
			shifts = 0x7efc;

			for(i = 0; i < 16; i++) {
				if((shifts & 1) != 0) {
				c = ((c >> 2) | (c << 26));
				d = ((d >> 2) | (d << 26));
				} else {
				c = ((c >> 1) | (c << 27));
				d = ((d >> 1) | (d << 27));
				}
				shifts >>= 1;
				c &= 0x0fffffff;
				d &= 0x0fffffff;

				s = SKB[0, (c) & 0x3f] |
				SKB[1, ((c >> 6 ) & 0x03)|((c >> 7 ) & 0x3c)] |
				SKB[2, ((c >> 13) & 0x0f)|((c >> 14) & 0x30)] |
				SKB[3, ((c >> 20) & 0x01)|((c >> 21) & 0x06) | ((c >> 22) & 0x38)];

				t = SKB[4, (d) & 0x3f] |
				SKB[5, ((d >> 7 ) & 0x03) | ((d >> 8 ) & 0x3c)] |
				SKB[6,  (d >> 15) & 0x3f				] |
				SKB[7, ((d >> 21) & 0x0f) | ((d >> 22) & 0x30)];

				_key[i * 2]	   = ((t << 16) | (s & 0xffff));
				s						 = ((s >> 16) | (t & 0xffff0000));
				_key[(i * 2) + 1] =  (s << 4)  | (s >> 28);
			}
		}

		public void BlockEncrypt(byte[] input, int inOffset, byte[] output, int outOffset) {
			uint t;
			int i;
			uint[] lr = new uint[2];

			lr[0] = CipherUtil.GetIntLE(input, inOffset);
			lr[1] = CipherUtil.GetIntLE(input, inOffset + 4);

			initPerm(lr);

			t = (lr[1] << 1) | (lr[1] >> 31);
			lr[1] = (lr[0] << 1) | (lr[0] >> 31);
			lr[0] = t;

			for (i = 0; i < 32; i += 4) {
				desCipher1(lr, i);
				desCipher2(lr, i + 2);
			}

			lr[0] = (lr[0] >> 1) | (lr[0] << 31);
			lr[1] = (lr[1] >> 1) | (lr[1] << 31);

			finalPerm(lr);

			CipherUtil.PutIntLE(lr[0], output, outOffset);
			CipherUtil.PutIntLE(lr[1], output, outOffset + 4);
		}

		public void BlockDecrypt(byte[] input, int inOffset, byte[] output, int outOffset) {
			uint t;
			int i;
			uint[] lr = new uint[2];

			lr[0] = CipherUtil.GetIntLE(input, inOffset);
			lr[1] = CipherUtil.GetIntLE(input, inOffset + 4);

			initPerm(lr);

			t = (lr[1] << 1) | (lr[1] >> 31);
			lr[1] = (lr[0] << 1) | (lr[0] >> 31);
			lr[0] = t;

			for (i = 30; i > 0; i -= 4) {
				desCipher1(lr, i);
				desCipher2(lr, i - 2);
			}

			lr[0] = (lr[0] >> 1) | (lr[0] << 31);
			lr[1] = (lr[1] >> 1) | (lr[1] << 31);

			finalPerm(lr);

			CipherUtil.PutIntLE(lr[0], output, outOffset);
			CipherUtil.PutIntLE(lr[1], output, outOffset + 4);
		}

		private void desCipher1(uint[] lr, int i) {
			uint u = lr[1] ^ _key[i	];
			uint t = lr[1] ^ _key[i + 1];
			t = ((t >> 4) + (t << 28));
			lr[0] ^= (SPTRANS[1, (t	   ) & 0x3f] |
				SPTRANS[3, (t >> 8 ) & 0x3f] |
				SPTRANS[5, (t >> 16) & 0x3f] |
				SPTRANS[7, (t >> 24) & 0x3f] |
				SPTRANS[0, (u	   ) & 0x3f] |
				SPTRANS[2, (u >> 8 ) & 0x3f] |
				SPTRANS[4, (u >> 16) & 0x3f] |
				SPTRANS[6, (u >> 24) & 0x3f]);
		}

		private void desCipher2(uint[] lr, int i) {
			uint u = lr[0] ^ _key[i	];
			uint t = lr[0] ^ _key[i + 1];
			t = ((t >> 4) + (t << 28));
			lr[1] ^= (SPTRANS[1, (t	   ) & 0x3f] |
				SPTRANS[3, (t >> 8 ) & 0x3f] |
				SPTRANS[5, (t >> 16) & 0x3f] |
				SPTRANS[7, (t >> 24) & 0x3f] |
				SPTRANS[0, (u	   ) & 0x3f] |
				SPTRANS[2, (u >> 8 ) & 0x3f] |
				SPTRANS[4, (u >> 16) & 0x3f] |
				SPTRANS[6, (u >> 24) & 0x3f]);
		}

		private static void initPerm(uint[] lr) {
			uint t  = ((lr[1] >> 4) ^ lr[0])  & 0x0f0f0f0f;
			lr[0] ^= t;
			lr[1] ^= t << 4;
			t  = ((lr[0] >> 16) ^ lr[1]) & 0x0000ffff;
			lr[1] ^= t;
			lr[0] ^= t << 16;
			t  = ((lr[1] >> 2) ^ lr[0])  & 0x33333333;
			lr[0] ^= t;
			lr[1] ^= t << 2;
			t  = ((lr[0] >> 8) ^ lr[1])  & 0x00ff00ff;
			lr[1] ^= t;
			lr[0] ^= t << 8;
			t  = ((lr[1] >> 1) ^ lr[0])  & 0x55555555;
			lr[0] ^= t;
			lr[1] ^= t << 1;
		}

		private static void finalPerm(uint[] lr) {
			uint t  = ((lr[1] >> 1) ^ lr[0])  & 0x55555555;
			lr[0] ^= t;
			lr[1] ^= t << 1;
			t  = ((lr[0] >> 8) ^ lr[1])  & 0x00ff00ff;
			lr[1] ^= t;
			lr[0] ^= t << 8;
			t  = ((lr[1] >> 2) ^ lr[0])  & 0x33333333;
			lr[0] ^= t;
			lr[1] ^= t << 2;
			t  = ((lr[0] >> 16) ^ lr[1]) & 0x0000ffff;
			lr[1] ^= t;
			lr[0] ^= t << 16;
			t  = ((lr[1] >> 4) ^ lr[0])  & 0x0f0f0f0f;
			lr[0] ^= t;
			lr[1] ^= t << 4;
		}
	  
		public void EncryptCBC(byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset) {
			int nBlocks = inputLen / 8;
			for(int bc = 0; bc < nBlocks; bc++) {
				CipherUtil.BlockXor(input, inputOffset, 8, _iv, 0);
				BlockEncrypt(_iv, 0, output, outputOffset);
				Array.Copy(output, outputOffset, _iv, 0, 8);
				inputOffset  += 8;
				outputOffset += 8;
			}
		}
		
		public void DecryptCBC(byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset) {
			int nBlocks = inputLen / 8;
			for(int bc = 0; bc < nBlocks; bc++)	{
				BlockDecrypt(input, inputOffset, _temp, 0);
				for(int i = 0; i < 8; i++) {
					_temp[i] ^= _iv[i];
					_iv[i] = input[inputOffset + i];
					output[outputOffset + i] = _temp[i];
				}
				inputOffset  += 8;
				outputOffset += 8;
			}
		}
		
		/* 
		* Copyright (C) 1993 Eric Young
		*/
		private static readonly uint[,] SKB = new uint[,] {
		/* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
		{ 0x00000000,0x00000010,0x20000000,0x20000010,
		0x00010000,0x00010010,0x20010000,0x20010010,
		0x00000800,0x00000810,0x20000800,0x20000810,
		0x00010800,0x00010810,0x20010800,0x20010810,
		0x00000020,0x00000030,0x20000020,0x20000030,
		0x00010020,0x00010030,0x20010020,0x20010030,
		0x00000820,0x00000830,0x20000820,0x20000830,
		0x00010820,0x00010830,0x20010820,0x20010830,
		0x00080000,0x00080010,0x20080000,0x20080010,
		0x00090000,0x00090010,0x20090000,0x20090010,
		0x00080800,0x00080810,0x20080800,0x20080810,
		0x00090800,0x00090810,0x20090800,0x20090810,
		0x00080020,0x00080030,0x20080020,0x20080030,
		0x00090020,0x00090030,0x20090020,0x20090030,
		0x00080820,0x00080830,0x20080820,0x20080830,
		0x00090820,0x00090830,0x20090820,0x20090830 },
		/* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */
		{ 0x00000000,0x02000000,0x00002000,0x02002000,
		0x00200000,0x02200000,0x00202000,0x02202000,
		0x00000004,0x02000004,0x00002004,0x02002004,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -