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

📄 rijndael.java

📁 一个非常好的ssh客户端实现
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************** * * Copyright (c) 1999-2003 AppGate Network Security AB. All Rights Reserved. *  * This file contains Original Code and/or Modifications of Original Code as * defined in and that are subject to the MindTerm Public Source License, * Version 2.0, (the 'License'). You may not use this file except in compliance * with the License. *  * You should have received a copy of the MindTerm Public Source License * along with this software; see the file LICENSE.  If not, write to * AppGate Network Security AB, Otterhallegatan 2, SE-41118 Goteborg, SWEDEN * *****************************************************************************//* * Author's comment: The contents of this file is heavily based upon... * * Rijndael --pronounced Reindaal-- is a variable block-size (128-, 192- and * 256-bit), variable key-size (128-, 192- and 256-bit) symmetric cipher. * * Rijndael was written by Vincent Rijmen and Joan Daemen. * */package com.mindbright.security.cipher;import com.mindbright.jca.security.InvalidKeyException;public final class Rijndael extends BlockCipher {    private int[][] Ke; // encryption round keys    private int[][] Kd; // decryption round keys    private int ROUNDS;    public Rijndael() {    }    public int getBlockSize() {	return BLOCK_SIZE;    }    /**     * Expand a user-supplied key material into a session key.     *     * @param key  The 128/192/256-bit user-key to use.     * @exception  InvalidKeyException If the key is invalid.     */    public synchronized void initializeKey(byte[] key)	throws InvalidKeyException    {        if (key == null)            throw new InvalidKeyException("Empty key");        if (!(key.length == 16 || key.length == 24 || key.length == 32))             throw new InvalidKeyException("Incorrect key length");        ROUNDS = getRounds(key.length, BLOCK_SIZE);        Ke = new int[ROUNDS + 1][BC]; // encryption round keys        Kd = new int[ROUNDS + 1][BC]; // decryption round keys        int ROUND_KEY_COUNT = (ROUNDS + 1) * BC;        int KC = key.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++] = (key[j++] & 0xFF) << 24 |                      (key[j++] & 0xFF) << 16 |                      (key[j++] & 0xFF) <<  8 |                      (key[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;            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++];            }            // copy values into round key arrays            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++)    // inverse MixColumn where needed            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];            }    }    /**     * 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  out        The ciphertext.     * @param  outOffset  Index in out where output of ciphertext should start.     */    public void blockEncrypt(byte[] in, int inOffset, byte[] out, int outOffset)    {        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;        }        // last round is special        Ker = Ke[ROUNDS];        int tt = Ker[0];        out[outOffset + 0] = (byte)(S[(t0 >>> 24) & 0xFF] ^ (tt >>> 24));        out[outOffset + 1] = (byte)(S[(t1 >>> 16) & 0xFF] ^ (tt >>> 16));	out[outOffset + 2] = (byte)(S[(t2 >>>  8) & 0xFF] ^ (tt >>>  8));	out[outOffset + 3] = (byte)(S[ t3         & 0xFF] ^  tt        );        tt = Ker[1];	out[outOffset + 4] = (byte)(S[(t1 >>> 24) & 0xFF] ^ (tt >>> 24));	out[outOffset + 5] = (byte)(S[(t2 >>> 16) & 0xFF] ^ (tt >>> 16));	out[outOffset + 6] = (byte)(S[(t3 >>>  8) & 0xFF] ^ (tt >>>  8));	out[outOffset + 7] = (byte)(S[ t0         & 0xFF] ^  tt        );        tt = Ker[2];	out[outOffset + 8] = (byte)(S[(t2 >>> 24) & 0xFF] ^ (tt >>> 24));	out[outOffset + 9] = (byte)(S[(t3 >>> 16) & 0xFF] ^ (tt >>> 16));	out[outOffset +10] = (byte)(S[(t0 >>>  8) & 0xFF] ^ (tt >>>  8));	out[outOffset +11] = (byte)(S[ t1         & 0xFF] ^  tt        );        tt = Ker[3];	out[outOffset +12] = (byte)(S[(t3 >>> 24) & 0xFF] ^ (tt >>> 24));	out[outOffset +13] = (byte)(S[(t0 >>> 16) & 0xFF] ^ (tt >>> 16));	out[outOffset +14] = (byte)(S[(t1 >>>  8) & 0xFF] ^ (tt >>>  8));	out[outOffset +15] = (byte)(S[ t2         & 0xFF] ^  tt        );    }    /**     * 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  out        The plaintext.     * @param  inOffset   Index in out where output of plaintext should start.      */    public void blockDecrypt(byte[] in, int inOffset, byte[] out, int outOffset)    {        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] ^

⌨️ 快捷键说明

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