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

📄 rijndael_algorithm.java

📁 Its about cryptography example. useful for chatting with some sort of security
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
    // 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;            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];

⌨️ 快捷键说明

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