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

📄 rijndael.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.
 * 
 * ---------------------------------------------------------------------------
 * 
 * Rijndael was written by <a href="mailto:rijmen@esat.kuleuven.ac.be">Vincent
 * Rijmen</a> and <a href="mailto:Joan.Daemen@village.uunet.be">Joan Daemen</a>.
 * 
 * ---------------------------------------------------------------------------
 * 
 * I implemented this algorithm with reference to following products though the algorithm is known publicly.
 *   * MindTerm ( AppGate Network Security )
 */
using System;

namespace Routrek.Crypto
{
	public class Rijndael
	{
		byte[] _IV;
		int[][] _Ke;			// encryption round keys
		int[][] _Kd;			// decryption round keys
		private int _rounds;

		public Rijndael() {
			_IV = new byte[GetBlockSize()];
		}

		public int GetBlockSize() {
			return BLOCK_SIZE;
		}

		///////////////////////////////////////////////
		// set _IV
		///////////////////////////////////////////////
		public void SetIV(byte[] newiv) {
			Array.Copy(newiv, 0, _IV, 0, _IV.Length);
		}

		///////////////////////////////////////////////
		// set KEY
		///////////////////////////////////////////////
		public void InitializeKey(byte[] key) {
			if (key == null)
				throw new Exception("Empty key");
			//128bit or 192bit or 256bit
			if (!(key.Length == 16 || key.Length == 24 || key.Length == 32))
				throw new Exception("Incorrect key length");

			_rounds = getRounds(key.Length, GetBlockSize());
			_Ke = new int[_rounds + 1][]; 
			_Kd = new int[_rounds + 1][]; 
			int i, j;
			for(i=0; i<_rounds + 1; i++) {
				_Ke[i] = new int[BC];
				_Kd[i] = new int[BC];
			}

			int ROUND_KEY_COUNT = (_rounds + 1) * BC;
			int KC = key.Length / 4;
			int[] tk = new int[KC];

			for (i = 0, j = 0; i < KC; ) {
				tk[i++] = (key[j++] & 0xFF) << 24 |
				          (key[j++] & 0xFF) << 16 |
				          (key[j++] & 0xFF) <<  8 |
				          (key[j++] & 0xFF);
			}

			int t = 0;
			for (j = 0; (j < KC) && (t < ROUND_KEY_COUNT); j++, t++) {
				_Ke[t / BC][t % BC] = tk[j];
				_Kd[_rounds - (t / BC)][t % BC] = tk[j];
			}
			int tt, rconpointer = 0;
			while (t < ROUND_KEY_COUNT) {
				tt = tk[KC - 1];
				tk[0] ^= (S[(tt >> 16) & 0xFF] & 0xFF) << 24 ^
				         (S[(tt >>  8) & 0xFF] & 0xFF) << 16 ^
				         (S[ tt	       & 0xFF] & 0xFF) <<  8 ^
				         (S[(tt >> 24) & 0xFF] & 0xFF)       ^
				         (rcon[rconpointer++]  & 0xFF) << 24;

				if (KC != 8) {
					for (i = 1, j = 0; i < KC; )
						tk[i++] ^= tk[j++];
				}
				else {
					for (i = 1, j = 0; i < KC / 2; )
						tk[i++] ^= tk[j++];
					tt = tk[KC / 2 - 1];
					tk[KC / 2] ^= (S[ tt        & 0xFF] & 0xFF)       ^
					              (S[(tt >>  8) & 0xFF] & 0xFF) <<  8 ^
								  (S[(tt >> 16) & 0xFF] & 0xFF) << 16 ^
								  (S[(tt >> 24) & 0xFF] & 0xFF) << 24;
					for (j = KC / 2, i = j + 1; i < KC; )
						tk[i++] ^= tk[j++];
				}
				for (j = 0; (j < KC) && (t < ROUND_KEY_COUNT); j++, t++) {
					_Ke[t / BC][t % BC] = tk[j];
					_Kd[_rounds - (t / BC)][t % BC] = tk[j];
				}
			}
			for (int r = 1; r < _rounds; r++){
				for (j = 0; j < BC; j++) {
					tt = _Kd[r][j];
					_Kd[r][j] = U1[(tt >> 24) & 0xFF] ^
					 	       U2[(tt >> 16) & 0xFF] ^
							   U3[(tt >>  8) & 0xFF] ^
							   U4[ tt        & 0xFF];
				}
			}
		}

		public static int getRounds(int keySize, int blockSize) {
			switch (keySize) {
				case 16:
					return blockSize == 16 ? 10 : (blockSize == 24 ? 12 : 14);
				case 24:
					return blockSize != 32 ? 12 : 14;
				default: 
					return 14;
			}
		}

		public void encryptCBC(byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset) {
			int block_size = GetBlockSize();
			int nBlocks = inputLen / block_size;
			for(int bc = 0; bc < nBlocks; bc++) {
				CipherUtil.BlockXor(input, inputOffset, block_size, _IV, 0);
				blockEncrypt(_IV, 0, output, outputOffset);
				Array.Copy(output, outputOffset, _IV, 0, block_size);
				inputOffset  += block_size;
				outputOffset += block_size;
			}
		}

		public void decryptCBC(byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset) {
			int block_size = GetBlockSize();
			byte[] tmpBlk = new byte[block_size];
			int nBlocks = inputLen / block_size;
			for(int bc = 0; bc < nBlocks; bc++) 
			{
				blockDecrypt(input, inputOffset, tmpBlk, 0);
				for(int i = 0; i < block_size; i++) 
				{
					tmpBlk[i] ^= _IV[i];
					_IV[i] = input[inputOffset + i];
					output[outputOffset + i] = tmpBlk[i];
				}
				inputOffset  += block_size;
				outputOffset += block_size;
			}
		}

		public void blockEncrypt(byte[] src, int inOffset, byte[] dst, int outOffset) {
			int[] Ker  = _Ke[0];

			int t0 = ((src[inOffset++] & 0xFF) << 24 |
			          (src[inOffset++] & 0xFF) << 16 |
			          (src[inOffset++] & 0xFF) <<  8 |
			          (src[inOffset++] & 0xFF)        ) ^ Ker[0];
			int t1 = ((src[inOffset++] & 0xFF) << 24 |
			          (src[inOffset++] & 0xFF) << 16 |
			          (src[inOffset++] & 0xFF) <<  8 |
			          (src[inOffset++] & 0xFF)        ) ^ Ker[1];
			int t2 = ((src[inOffset++] & 0xFF) << 24 |
			          (src[inOffset++] & 0xFF) << 16 |
			          (src[inOffset++] & 0xFF) <<  8 |
			          (src[inOffset++] & 0xFF)        ) ^ Ker[2];
			int t3 = ((src[inOffset++] & 0xFF) << 24 |
			          (src[inOffset++] & 0xFF) << 16 |
			          (src[inOffset++] & 0xFF) <<  8 |
			          (src[inOffset++] & 0xFF)        ) ^ Ker[3];

			int a0, a1, a2, a3;
			for (int r = 1; r < _rounds; r++) {
				Ker = _Ke[r];
				a0 = (T1[(t0 >> 24) & 0xFF] ^
				      T2[(t1 >> 16) & 0xFF] ^
				      T3[(t2 >>  8) & 0xFF] ^
				      T4[ t3        & 0xFF]  ) ^ Ker[0];
				a1 = (T1[(t1 >> 24) & 0xFF] ^
				      T2[(t2 >> 16) & 0xFF] ^
				      T3[(t3 >>  8) & 0xFF] ^
				      T4[ t0        & 0xFF]  ) ^ Ker[1];
				a2 = (T1[(t2 >> 24) & 0xFF] ^
				      T2[(t3 >> 16) & 0xFF] ^
				      T3[(t0 >>  8) & 0xFF] ^
				      T4[ t1        & 0xFF]  ) ^ Ker[2];
				a3 = (T1[(t3 >> 24) & 0xFF] ^
				      T2[(t0 >> 16) & 0xFF] ^
				      T3[(t1 >>  8) & 0xFF] ^
				      T4[ t2        & 0xFF]  ) ^ Ker[3];
				t0 = a0;
				t1 = a1;
				t2 = a2;
				t3 = a3;
			}

			Ker = _Ke[_rounds];
			int tt = Ker[0];
			dst[outOffset + 0] = (byte)(S[(t0 >> 24) & 0xFF] ^ (tt >> 24));
			dst[outOffset + 1] = (byte)(S[(t1 >> 16) & 0xFF] ^ (tt >> 16));
			dst[outOffset + 2] = (byte)(S[(t2 >>  8) & 0xFF] ^ (tt >>  8));
			dst[outOffset + 3] = (byte)(S[ t3        & 0xFF] ^  tt	       );
			tt = Ker[1];
			dst[outOffset + 4] = (byte)(S[(t1 >> 24) & 0xFF] ^ (tt >> 24));
			dst[outOffset + 5] = (byte)(S[(t2 >> 16) & 0xFF] ^ (tt >> 16));
			dst[outOffset + 6] = (byte)(S[(t3 >>  8) & 0xFF] ^ (tt >>  8));
			dst[outOffset + 7] = (byte)(S[ t0		 & 0xFF] ^  tt		);
			tt = Ker[2];
			dst[outOffset + 8] = (byte)(S[(t2 >> 24) & 0xFF] ^ (tt >> 24));
			dst[outOffset + 9] = (byte)(S[(t3 >> 16) & 0xFF] ^ (tt >> 16));
			dst[outOffset +10] = (byte)(S[(t0 >>  8) & 0xFF] ^ (tt >>  8));
			dst[outOffset +11] = (byte)(S[ t1		 & 0xFF] ^  tt		);
			tt = Ker[3];
			dst[outOffset +12] = (byte)(S[(t3 >> 24) & 0xFF] ^ (tt >> 24));
			dst[outOffset +13] = (byte)(S[(t0 >> 16) & 0xFF] ^ (tt >> 16));
			dst[outOffset +14] = (byte)(S[(t1 >>  8) & 0xFF] ^ (tt >>  8));
			dst[outOffset +15] = (byte)(S[ t2		 & 0xFF] ^  tt		);
		}

		public void blockDecrypt(byte[] src, int inOffset, byte[] dst, int outOffset) {
			int[] Kdr = _Kd[0];

			int t0 = ((src[inOffset++] & 0xFF) << 24 |
			          (src[inOffset++] & 0xFF) << 16 |

⌨️ 快捷键说明

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