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

📄 rijndael.java

📁 纯java AES实现
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
        rdk[d + 2] = rek[e + 2];        rdk[d + 3] = rek[e + 3];    }        /**     * Setup the AES key schedule for encryption, decryption, or both.     *     * @param   cipherKey   the cipher key (128, 192, or 256 bits).     * @param   keyBits     size of the cipher key in bits.     * @param   direction   cipher direction (DIR_ENCRYPT, DIR_DECRYPT, or DIR_BOTH).     */    public void makeKey(byte[] cipherKey, int keyBits, int direction)    throws RuntimeException {        // check key size:        if (keyBits != 128 && keyBits != 192 && keyBits != 256) {            throw new RuntimeException("Invalid AES key size (" + keyBits + " bits)");        }        Nk = keyBits >>> 5;        Nr = Nk + 6;        Nw = 4*(Nr + 1);        rek = new int[Nw];        rdk = new int[Nw];        if ((direction & DIR_BOTH) != 0) {            expandKey(cipherKey);            /*            for (int r = 0; r <= Nr; r++) {                System.out.print("RK" + r + "=");                for (int i = 0; i < 4; i++) {                        int w = rek[4*r + i];                        System.out.print(" " + Integer.toHexString(w));                }                System.out.println();            }             */            if ((direction & DIR_DECRYPT) != 0) {                invertKey();            }        }    }        /**     * Setup the AES key schedule (any cipher direction).     *     * @param   cipherKey   the cipher key (128, 192, or 256 bits).     * @param   keyBits     size of the cipher key in bits.     */    public void makeKey(byte[] cipherKey, int keyBits)    throws RuntimeException {        makeKey(cipherKey, keyBits, DIR_BOTH);    }        /**     * Encrypt exactly one block (BLOCK_SIZE bytes) of plaintext.     *     * @param   pt          plaintext block.     * @param   ct          ciphertext block.     */    public byte[] encryptBlock(byte[] pt, byte[] ct) {        /*         * map byte array block to cipher state         * and add initial round key:         */        int k = 0, v;        int t0   = ((pt[ 0]       ) << 24 |                (pt[ 1] & 0xff) << 16 |                (pt[ 2] & 0xff) <<  8 |                (pt[ 3] & 0xff)        ) ^ rek[0];        int t1   = ((pt[ 4]       ) << 24 |                (pt[ 5] & 0xff) << 16 |                (pt[ 6] & 0xff) <<  8 |                (pt[ 7] & 0xff)        ) ^ rek[1];        int t2   = ((pt[ 8]       ) << 24 |                (pt[ 9] & 0xff) << 16 |                (pt[10] & 0xff) <<  8 |                (pt[11] & 0xff)        ) ^ rek[2];        int t3   = ((pt[12]       ) << 24 |                (pt[13] & 0xff) << 16 |                (pt[14] & 0xff) <<  8 |                (pt[15] & 0xff)        ) ^ rek[3];        /*         * Nr - 1 full rounds:         */        for (int r = 1; r < Nr; r++) {            k += 4;            int a0 =                    Te0[(t0 >>> 24)       ] ^                    Te1[(t1 >>> 16) & 0xff] ^                    Te2[(t2 >>>  8) & 0xff] ^                    Te3[(t3       ) & 0xff] ^                    rek[k    ];            int a1 =                    Te0[(t1 >>> 24)       ] ^                    Te1[(t2 >>> 16) & 0xff] ^                    Te2[(t3 >>>  8) & 0xff] ^                    Te3[(t0       ) & 0xff] ^                    rek[k + 1];            int a2 =                    Te0[(t2 >>> 24)       ] ^                    Te1[(t3 >>> 16) & 0xff] ^                    Te2[(t0 >>>  8) & 0xff] ^                    Te3[(t1       ) & 0xff] ^                    rek[k + 2];            int a3 =                    Te0[(t3 >>> 24)       ] ^                    Te1[(t0 >>> 16) & 0xff] ^                    Te2[(t1 >>>  8) & 0xff] ^                    Te3[(t2       ) & 0xff] ^                    rek[k + 3];            t0 = a0; t1 = a1; t2 = a2; t3 = a3;        }        /*         * last round lacks MixColumn:         */        k += 4;                v = rek[k    ];        ct[ 0] = (byte)(Se[(t0 >>> 24)       ] ^ (v >>> 24));        ct[ 1] = (byte)(Se[(t1 >>> 16) & 0xff] ^ (v >>> 16));        ct[ 2] = (byte)(Se[(t2 >>>  8) & 0xff] ^ (v >>>  8));        ct[ 3] = (byte)(Se[(t3       ) & 0xff] ^ (v       ));                v = rek[k + 1];        ct[ 4] = (byte)(Se[(t1 >>> 24)       ] ^ (v >>> 24));        ct[ 5] = (byte)(Se[(t2 >>> 16) & 0xff] ^ (v >>> 16));        ct[ 6] = (byte)(Se[(t3 >>>  8) & 0xff] ^ (v >>>  8));        ct[ 7] = (byte)(Se[(t0       ) & 0xff] ^ (v       ));                v = rek[k + 2];        ct[ 8] = (byte)(Se[(t2 >>> 24)       ] ^ (v >>> 24));        ct[ 9] = (byte)(Se[(t3 >>> 16) & 0xff] ^ (v >>> 16));        ct[10] = (byte)(Se[(t0 >>>  8) & 0xff] ^ (v >>>  8));        ct[11] = (byte)(Se[(t1       ) & 0xff] ^ (v       ));                v = rek[k + 3];        ct[12] = (byte)(Se[(t3 >>> 24)       ] ^ (v >>> 24));        ct[13] = (byte)(Se[(t0 >>> 16) & 0xff] ^ (v >>> 16));        ct[14] = (byte)(Se[(t1 >>>  8) & 0xff] ^ (v >>>  8));        ct[15] = (byte)(Se[(t2       ) & 0xff] ^ (v       ));                return ct;    }        /**     * Decrypt exactly one block (BLOCK_SIZE bytes) of ciphertext.     *     * @param   ct          ciphertext block.     * @param   pt          plaintext block.     */    public byte[] decryptBlock(byte[] ct, byte[] pt) {        /*         * map byte array block to cipher state         * and add initial round key:         */        int k = 0, v;        int t0 =   ((ct[ 0]       ) << 24 |                (ct[ 1] & 0xff) << 16 |                (ct[ 2] & 0xff) <<  8 |                (ct[ 3] & 0xff)        ) ^ rdk[0];        int t1 =   ((ct[ 4]       ) << 24 |                (ct[ 5] & 0xff) << 16 |                (ct[ 6] & 0xff) <<  8 |                (ct[ 7] & 0xff)        ) ^ rdk[1];        int t2 =   ((ct[ 8]       ) << 24 |                (ct[ 9] & 0xff) << 16 |                (ct[10] & 0xff) <<  8 |                (ct[11] & 0xff)        ) ^ rdk[2];        int t3 =   ((ct[12]       ) << 24 |                (ct[13] & 0xff) << 16 |                (ct[14] & 0xff) <<  8 |                (ct[15] & 0xff)        ) ^ rdk[3];        /*         * Nr - 1 full rounds:         */        for (int r = 1; r < Nr; r++) {            k += 4;            int a0 =                    Td0[(t0 >>> 24)       ] ^                    Td1[(t3 >>> 16) & 0xff] ^                    Td2[(t2 >>>  8) & 0xff] ^                    Td3[(t1       ) & 0xff] ^                    rdk[k    ];            int a1 =                    Td0[(t1 >>> 24)       ] ^                    Td1[(t0 >>> 16) & 0xff] ^                    Td2[(t3 >>>  8) & 0xff] ^                    Td3[(t2       ) & 0xff] ^                    rdk[k + 1];            int a2 =                    Td0[(t2 >>> 24)       ] ^                    Td1[(t1 >>> 16) & 0xff] ^                    Td2[(t0 >>>  8) & 0xff] ^                    Td3[(t3       ) & 0xff] ^                    rdk[k + 2];            int a3 =                    Td0[(t3 >>> 24)       ] ^                    Td1[(t2 >>> 16) & 0xff] ^                    Td2[(t1 >>>  8) & 0xff] ^                    Td3[(t0       ) & 0xff] ^                    rdk[k + 3];            t0 = a0; t1 = a1; t2 = a2; t3 = a3;        }        /*         * last round lacks MixColumn:         */        k += 4;                v = rdk[k    ];        pt[ 0] = (byte)(Sd[(t0 >>> 24)       ] ^ (v >>> 24));        pt[ 1] = (byte)(Sd[(t3 >>> 16) & 0xff] ^ (v >>> 16));        pt[ 2] = (byte)(Sd[(t2 >>>  8) & 0xff] ^ (v >>>  8));        pt[ 3] = (byte)(Sd[(t1       ) & 0xff] ^ (v       ));                v = rdk[k + 1];        pt[ 4] = (byte)(Sd[(t1 >>> 24)       ] ^ (v >>> 24));        pt[ 5] = (byte)(Sd[(t0 >>> 16) & 0xff] ^ (v >>> 16));        pt[ 6] = (byte)(Sd[(t3 >>>  8) & 0xff] ^ (v >>>  8));        pt[ 7] = (byte)(Sd[(t2       ) & 0xff] ^ (v       ));                v = rdk[k + 2];        pt[ 8] = (byte)(Sd[(t2 >>> 24)       ] ^ (v >>> 24));        pt[ 9] = (byte)(Sd[(t1 >>> 16) & 0xff] ^ (v >>> 16));        pt[10] = (byte)(Sd[(t0 >>>  8) & 0xff] ^ (v >>>  8));        pt[11] = (byte)(Sd[(t3       ) & 0xff] ^ (v       ));                v = rdk[k + 3];        pt[12] = (byte)(Sd[(t3 >>> 24)       ] ^ (v >>> 24));        pt[13] = (byte)(Sd[(t2 >>> 16) & 0xff] ^ (v >>> 16));        pt[14] = (byte)(Sd[(t1 >>>  8) & 0xff] ^ (v >>>  8));        pt[15] = (byte)(Sd[(t0       ) & 0xff] ^ (v       ));                return pt;    }            public byte[] encryptArray(byte[] message, int offset) throws CryptoException {        //Check for a bad offset        if(offset > message.length) {            throw new CryptoException("Offset is greater than length of message");        }                //Length of message to process        int length = message.length - offset;                //Number of whole blocks        int numOfBlocks = length / BLOCK_SIZE;                //Length of the last part        int lengthOfLastPart = length - (numOfBlocks * BLOCK_SIZE);                //If message was mutliple of BLOCK_SIZE        if(lengthOfLastPart == 0) {            lengthOfLastPart = BLOCK_SIZE;            numOfBlocks = numOfBlocks - 1;        }                byte[] result = new byte[0];        byte[] block = new byte[BLOCK_SIZE];                //Process whole blocks        for(int i = 0; i < numOfBlocks; i++) {            System.arraycopy(message, offset + (i * BLOCK_SIZE), block, 0, BLOCK_SIZE);            result = Util.addByteArrays(result, encryptBlock(block, new byte[BLOCK_SIZE]));        }                //Now do the last part (or last block if message was multiple of BLOCK_SIZE)        byte last[] = new byte[lengthOfLastPart];        System.arraycopy(message, offset + (numOfBlocks * BLOCK_SIZE), last, 0, lengthOfLastPart);                //Number of padding bytes required        int numOfPads = BLOCK_SIZE - last.length;                //If last block is equal to the block size we need a whole new padding block        if(numOfPads == 0){            numOfPads = BLOCK_SIZE;        }                //Set the padding bytes        byte pads[] = new byte[numOfPads];        for(int i = 0; i < numOfPads; i++) {            pads[i]=(byte)numOfPads;        }                if(numOfPads != BLOCK_SIZE) {            //Add the padding bytes to the input            last = Util.addByteArrays(last, pads);        } else {            //If last block passed was 0 bytes long, just return a 16 byte padding block            if(last.length == 0) {                last = pads;            }                        //Return block plus 16 byte padding block            result = Util.addByteArrays(encryptBlock(last, new byte[BLOCK_SIZE]), encryptBlock(pads, new byte[BLOCK_SIZE]));            return result;        }                result = Util.addByteArrays(result, encryptBlock(last, new byte[BLOCK_SIZE]));                return result;    }        public byte[] decryptArray(byte[] message, int offset) throws CryptoException {        //Check for a bad offset        if(offset > message.length) {            throw new CryptoException("Offset is greater than length of message");        }                //Length of message to process        int length = message.length - offset;                //Number of whole blocks        int numOfBlocks = length / BLOCK_SIZE;                //Length of the last part        int lengthOfLastPart = length - (numOfBlocks * BLOCK_SIZE);                //If message was mutliple of BLOCK_SIZE        if(lengthOfLastPart == 0) {            lengthOfLastPart = BLOCK_SIZE;            numOfBlocks = numOfBlocks - 1;        }                byte[] result = new byte[0];        byte[] block = new byte[BLOCK_SIZE];                //Process whole blocks        for(int i = 0; i < numOfBlocks; i++) {            System.arraycopy(message, offset + (i * BLOCK_SIZE), block, 0, BLOCK_SIZE);            result = Util.addByteArrays(result, decryptBlock(block, new byte[BLOCK_SIZE]));        }                //Now do the last part (or last block if message was multiple of BLOCK_SIZE)        byte last[] = new byte[lengthOfLastPart];        System.arraycopy(message, offset + (numOfBlocks * BLOCK_SIZE), last, 0, lengthOfLastPart);                //Decrypt the last block        byte[] tmp = decryptBlock(last, new byte[BLOCK_SIZE]);                int numOfPads = tmp[tmp.length - 1];                byte[] lastBlock = new byte[BLOCK_SIZE - numOfPads];                System.arraycopy(tmp, 0, lastBlock, 0, lastBlock.length);                result = Util.addByteArrays(result, lastBlock);                return result;    }        /**     * Compares two byte arrays for equality.     *     * @return true if the arrays have identical contents     */    public static final boolean areEqual(byte[] a, byte[] b) {        int aLength = a.length;        if (aLength != b.length)            return false;        for (int i = 0; i < aLength; i++)            if (a[i] != b[i])                return false;        return true;    }        /**     * Destroy all sensitive information in this object.     */    protected final void finalize() {        if (rek != null) {            for (int i = 0; i < rek.length; i++) {                rek[i] = 0;            }            rek = null;        }        if (rdk != null) {            for (int i = 0; i < rdk.length; i++) {                rdk[i] = 0;            }            rdk = null;        }    }    }

⌨️ 快捷键说明

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