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

📄 rijndael_algorithm.java

📁 用JAVA编写的rijndael工具
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
			for (i = 0; i < 64; i++) {
				for (j = 0; j < 4; j++)
					System.out.print("0x" + intToString(T7[i * 4 + j]) + ", ");
				System.out.println();
			}
			System.out.println();
			System.out.println("T8[]:");
			for (i = 0; i < 64; i++) {
				for (j = 0; j < 4; j++)
					System.out.print("0x" + intToString(T8[i * 4 + j]) + ", ");
				System.out.println();
			}

			System.out.println();
			System.out.println("U1[]:");
			for (i = 0; i < 64; i++) {
				for (j = 0; j < 4; j++)
					System.out.print("0x" + intToString(U1[i * 4 + j]) + ", ");
				System.out.println();
			}
			System.out.println();
			System.out.println("U2[]:");
			for (i = 0; i < 64; i++) {
				for (j = 0; j < 4; j++)
					System.out.print("0x" + intToString(U2[i * 4 + j]) + ", ");
				System.out.println();
			}
			System.out.println();
			System.out.println("U3[]:");
			for (i = 0; i < 64; i++) {
				for (j = 0; j < 4; j++)
					System.out.print("0x" + intToString(U3[i * 4 + j]) + ", ");
				System.out.println();
			}
			System.out.println();
			System.out.println("U4[]:");
			for (i = 0; i < 64; i++) {
				for (j = 0; j < 4; j++)
					System.out.print("0x" + intToString(U4[i * 4 + j]) + ", ");
				System.out.println();
			}

			System.out.println();
			System.out.println("rcon[]:");
			for (i = 0; i < 5; i++) {
				for (j = 0; j < 6; j++)
					System.out.print("0x" + byteToString(rcon[i * 6 + j])
							+ ", ");
				System.out.println();
			}

			System.out.println();
			System.out.println("Total initialization time: " + time + " ms.");
			System.out.println();
		}
	}

	// multiply two elements of GF(2^m)
	static final int mul(int a, int b) {
		return (a != 0 && b != 0) ? alog[(log[a & 0xFF] + log[b & 0xFF]) % 255]
				: 0;
	}

	// convenience method used in generating Transposition boxes
	static final int mul4(int a, byte[] b) {
		if (a == 0)
			return 0;
		a = log[a & 0xFF];
		int a0 = (b[0] != 0) ? alog[(a + log[b[0] & 0xFF]) % 255] & 0xFF : 0;
		int a1 = (b[1] != 0) ? alog[(a + log[b[1] & 0xFF]) % 255] & 0xFF : 0;
		int a2 = (b[2] != 0) ? alog[(a + log[b[2] & 0xFF]) % 255] & 0xFF : 0;
		int a3 = (b[3] != 0) ? alog[(a + log[b[3] & 0xFF]) % 255] & 0xFF : 0;
		return a0 << 24 | a1 << 16 | a2 << 8 | a3;
	}

	// Basic API methods
	// ...........................................................................

	/**
	 * Convenience method to expand a user-supplied key material into a session
	 * key, assuming Rijndael's default block size (128-bit).
	 * 
	 * @param key
	 *            The 128/192/256-bit user-key to use.
	 * @exception InvalidKeyException
	 *                If the key is invalid.
	 */
	public static Object makeKey(byte[] k) throws InvalidKeyException {
		return makeKey(k, BLOCK_SIZE);
	}

	/**
	 * Convenience method to encrypt exactly one block of plaintext, assuming
	 * Rijndael's default block size (128-bit).
	 * 
	 * @param in
	 *            The plaintext.
	 * @param inOffset
	 *            Index of in from which to start considering data.
	 * @param sessionKey
	 *            The session key to use for encryption.
	 * @return The ciphertext generated from a plaintext using the session key.
	 */
	public static byte[] blockEncrypt(byte[] in, int inOffset, Object sessionKey) {
		if (DEBUG)
			trace(IN, "blockEncrypt(" + in + ", " + inOffset + ", "
					+ sessionKey + ")");
		int[][] Ke = (int[][]) ((Object[]) sessionKey)[0]; // extract
															// encryption round
															// keys
		int ROUNDS = Ke.length - 1;
		int[] Ker = Ke[0];

		// plaintext to ints + key
		int t0 = ((in[inOffset++] & 0xFF) << 24 | (in[inOffset++] & 0xFF) << 16
				| (in[inOffset++] & 0xFF) << 8 | (in[inOffset++] & 0xFF))
				^ Ker[0];
		int t1 = ((in[inOffset++] & 0xFF) << 24 | (in[inOffset++] & 0xFF) << 16
				| (in[inOffset++] & 0xFF) << 8 | (in[inOffset++] & 0xFF))
				^ Ker[1];
		int t2 = ((in[inOffset++] & 0xFF) << 24 | (in[inOffset++] & 0xFF) << 16
				| (in[inOffset++] & 0xFF) << 8 | (in[inOffset++] & 0xFF))
				^ Ker[2];
		int t3 = ((in[inOffset++] & 0xFF) << 24 | (in[inOffset++] & 0xFF) << 16
				| (in[inOffset++] & 0xFF) << 8 | (in[inOffset++] & 0xFF))
				^ Ker[3];

		int a0, a1, a2, a3;
		for (int r = 1; r < ROUNDS; r++) { // apply round transforms
			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;
			if (DEBUG && debuglevel > 6)
				System.out.println("CT" + r + "=" + intToString(t0)
						+ intToString(t1) + intToString(t2) + intToString(t3));
		}

		// last round is special
		byte[] result = new byte[BLOCK_SIZE]; // the resulting ciphertext
		Ker = Ke[ROUNDS];
		int tt = Ker[0];
		result[0] = (byte) (S[(t0 >>> 24) & 0xFF] ^ (tt >>> 24));
		result[1] = (byte) (S[(t1 >>> 16) & 0xFF] ^ (tt >>> 16));
		result[2] = (byte) (S[(t2 >>> 8) & 0xFF] ^ (tt >>> 8));
		result[3] = (byte) (S[t3 & 0xFF] ^ tt);
		tt = Ker[1];
		result[4] = (byte) (S[(t1 >>> 24) & 0xFF] ^ (tt >>> 24));
		result[5] = (byte) (S[(t2 >>> 16) & 0xFF] ^ (tt >>> 16));
		result[6] = (byte) (S[(t3 >>> 8) & 0xFF] ^ (tt >>> 8));
		result[7] = (byte) (S[t0 & 0xFF] ^ tt);
		tt = Ker[2];
		result[8] = (byte) (S[(t2 >>> 24) & 0xFF] ^ (tt >>> 24));
		result[9] = (byte) (S[(t3 >>> 16) & 0xFF] ^ (tt >>> 16));
		result[10] = (byte) (S[(t0 >>> 8) & 0xFF] ^ (tt >>> 8));
		result[11] = (byte) (S[t1 & 0xFF] ^ tt);
		tt = Ker[3];
		result[12] = (byte) (S[(t3 >>> 24) & 0xFF] ^ (tt >>> 24));
		result[13] = (byte) (S[(t0 >>> 16) & 0xFF] ^ (tt >>> 16));
		result[14] = (byte) (S[(t1 >>> 8) & 0xFF] ^ (tt >>> 8));
		result[15] = (byte) (S[t2 & 0xFF] ^ tt);
		if (DEBUG && debuglevel > 6) {
			System.out.println("CT=" + toString(result));
			System.out.println();
		}
		if (DEBUG)
			trace(OUT, "blockEncrypt()");
		return result;
	}

	/**
	 * Convenience method to decrypt exactly one block of plaintext, assuming
	 * Rijndael's default block size (128-bit).
	 * 
	 * @param in
	 *            The ciphertext.
	 * @param inOffset
	 *            Index of in from which to start considering data.
	 * @param sessionKey
	 *            The session key to use for decryption.
	 * @return The plaintext generated from a ciphertext using the session key.
	 */
	public static byte[] blockDecrypt(byte[] in, int inOffset, Object sessionKey) {
		if (DEBUG)
			trace(IN, "blockDecrypt(" + in + ", " + inOffset + ", "
					+ sessionKey + ")");
		int[][] Kd = (int[][]) ((Object[]) sessionKey)[1]; // extract
															// decryption round
															// keys
		int ROUNDS = Kd.length - 1;
		int[] Kdr = Kd[0];

		// ciphertext to ints + key
		int t0 = ((in[inOffset++] & 0xFF) << 24 | (in[inOffset++] & 0xFF) << 16
				| (in[inOffset++] & 0xFF) << 8 | (in[inOffset++] & 0xFF))
				^ Kdr[0];
		int t1 = ((in[inOffset++] & 0xFF) << 24 | (in[inOffset++] & 0xFF) << 16
				| (in[inOffset++] & 0xFF) << 8 | (in[inOffset++] & 0xFF))
				^ Kdr[1];
		int t2 = ((in[inOffset++] & 0xFF) << 24 | (in[inOffset++] & 0xFF) << 16
				| (in[inOffset++] & 0xFF) << 8 | (in[inOffset++] & 0xFF))
				^ Kdr[2];
		int t3 = ((in[inOffset++] & 0xFF) << 24 | (in[inOffset++] & 0xFF) << 16
				| (in[inOffset++] & 0xFF) << 8 | (in[inOffset++] & 0xFF))
				^ Kdr[3];

		int a0, a1, a2, a3;
		for (int r = 1; r < ROUNDS; r++) { // apply round transforms
			Kdr = Kd[r];
			a0 = (T5[(t0 >>> 24) & 0xFF] ^ T6[(t3 >>> 16) & 0xFF]
					^ T7[(t2 >>> 8) & 0xFF] ^ T8[t1 & 0xFF])
					^ Kdr[0];
			a1 = (T5[(t1 >>> 24) & 0xFF] ^ T6[(t0 >>> 16) & 0xFF]
					^ T7[(t3 >>> 8) & 0xFF] ^ T8[t2 & 0xFF])
					^ Kdr[1];
			a2 = (T5[(t2 >>> 24) & 0xFF] ^ T6[(t1 >>> 16) & 0xFF]
					^ T7[(t0 >>> 8) & 0xFF] ^ T8[t3 & 0xFF])
					^ Kdr[2];
			a3 = (T5[(t3 >>> 24) & 0xFF] ^ T6[(t2 >>> 16) & 0xFF]
					^ T7[(t1 >>> 8) & 0xFF] ^ T8[t0 & 0xFF])
					^ Kdr[3];
			t0 = a0;
			t1 = a1;
			t2 = a2;
			t3 = a3;
			if (DEBUG && debuglevel > 6)
				System.out.println("PT" + r + "=" + intToString(t0)
						+ intToString(t1) + intToString(t2) + intToString(t3));
		}

		// last round is special
		byte[] result = new byte[16]; // the resulting plaintext
		Kdr = Kd[ROUNDS];
		int tt = Kdr[0];
		result[0] = (byte) (Si[(t0 >>> 24) & 0xFF] ^ (tt >>> 24));
		result[1] = (byte) (Si[(t3 >>> 16) & 0xFF] ^ (tt >>> 16));
		result[2] = (byte) (Si[(t2 >>> 8) & 0xFF] ^ (tt >>> 8));
		result[3] = (byte) (Si[t1 & 0xFF] ^ tt);
		tt = Kdr[1];
		result[4] = (byte) (Si[(t1 >>> 24) & 0xFF] ^ (tt >>> 24));
		result[5] = (byte) (Si[(t0 >>> 16) & 0xFF] ^ (tt >>> 16));
		result[6] = (byte) (Si[(t3 >>> 8) & 0xFF] ^ (tt >>> 8));
		result[7] = (byte) (Si[t2 & 0xFF] ^ tt);
		tt = Kdr[2];
		result[8] = (byte) (Si[(t2 >>> 24) & 0xFF] ^ (tt >>> 24));
		result[9] = (byte) (Si[(t1 >>> 16) & 0xFF] ^ (tt >>> 16));
		result[10] = (byte) (Si[(t0 >>> 8) & 0xFF] ^ (tt >>> 8));
		result[11] = (byte) (Si[t3 & 0xFF] ^ tt);
		tt = Kdr[3];
		result[12] = (byte) (Si[(t3 >>> 24) & 0xFF] ^ (tt >>> 24));
		result[13] = (byte) (Si[(t2 >>> 16) & 0xFF] ^ (tt >>> 16));
		result[14] = (byte) (Si[(t1 >>> 8) & 0xFF] ^ (tt >>> 8));
		result[15] = (byte) (Si[t0 & 0xFF] ^ tt);
		if (DEBUG && debuglevel > 6) {
			System.out.println("PT=" + toString(result));
			System.out.println();
		}
		if (DEBUG)
			trace(OUT, "blockDecrypt()");
		return result;
	}

	/** A basic symmetric encryption/decryption test. */
	public static boolean self_test() {
		return self_test(BLOCK_SIZE);
	}

	// Rijndael own methods
	// ...........................................................................

	/** @return The default length in bytes of the Algorithm input block. */
	public static int blockSize() {
		return BLOCK_SIZE;
	}

	/**
	 * Expand a user-supplied key material into a session key.
	 * 
	 * @param key
	 *            The 128/192/256-bit user-key to use.
	 * @param blockSize
	 *            The block size in bytes of this Rijndael.
	 * @exception InvalidKeyException
	 *                If the key is invalid.
	 */
	public static synchronized Object makeKey(byte[] k, int blockSize)
			throws InvalidKeyException {
		if (DEBUG)
			trace(IN, "makeKey(" + k + ", " + blockSize + ")");
		if (k == null)
			throw new InvalidKeyException("Empty key");
		if (!(k.length == 16 || k.length == 24 || k.length == 32))
			throw new InvalidKeyException("Incorrect key length");
		int ROUNDS = getRounds(k.length, blockSize);
		int BC = blockSize / 4;
		int[][] Ke = new int[ROUNDS + 1][BC]; // encryption round keys
		int[][] Kd = new int[ROUNDS + 1][BC]; // decryption round keys
		int ROUND_KEY_COUNT = (ROUNDS + 1) * BC;
		int KC = k.length / 4;
		int[] tk = new int[KC];
		int i, j;

		// copy user material bytes into temporary ints
		for (i = 0, j = 0; i < KC;)
			tk[i++] = (k[j++] & 0xFF) << 24 | (k[j++] & 0xFF) << 16
					| (k[j++] & 0xFF) << 8 | (k[j++] & 0xFF);
		// copy values into round key arrays
		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) {
			// extrapolate using phi (the round key evolution function)
			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;

⌨️ 快捷键说明

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