📄 rijndael.java
字号:
Td1[Se[(w >>> 16) & 0xff] & 0xff] ^ Td2[Se[(w >>> 8) & 0xff] & 0xff] ^ Td3[Se[(w ) & 0xff] & 0xff]; w = rek[e + 2]; rdk[d + 2] = Td0[Se[(w >>> 24) ] & 0xff] ^ Td1[Se[(w >>> 16) & 0xff] & 0xff] ^ Td2[Se[(w >>> 8) & 0xff] & 0xff] ^ Td3[Se[(w ) & 0xff] & 0xff]; w = rek[e + 3]; rdk[d + 3] = Td0[Se[(w >>> 24) ] & 0xff] ^ Td1[Se[(w >>> 16) & 0xff] & 0xff] ^ Td2[Se[(w >>> 8) & 0xff] & 0xff] ^ Td3[Se[(w ) & 0xff] & 0xff]; d += 4; e -= 4; } rdk[d ] = rek[e ]; rdk[d + 1] = rek[e + 1]; 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 void encrypt(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 )); } /** * Decrypt exactly one block (BLOCK_SIZE bytes) of ciphertext. * * @param ct ciphertext block. * @param pt plaintext block. */ public void decrypt(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 )); } /** * 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; } } public static void main(String args[]){ DataOutputStream dataout = null; try{ Rijndael rl = new Rijndael(); String plaintxt = "abcdefgh"; String ciphertxt = "tdkkp_GYp_SYb8dp_b3dkDYb"; rl.makeKey(ciphertxt.getBytes(), 192); byte encryptR[] = rl.multiChunksEn(plaintxt.getBytes()); dataout = new DataOutputStream(new FileOutputStream(".\\encryptTXT.txt")); System.out.print("Encrypt: "); for (int a = 0; a < encryptR.length; a++) { System.out.print(encryptR[a] + " ");// dataout.write((encryptR[a]+" ").getBytes()); } dataout.write(encryptR); dataout.flush(); dataout.close(); dataout = null; System.out.println("");// byte []tc = {// (byte)0xDB,(byte)0xCD,(byte)0x37,(byte)0x50,// (byte)0xE0,(byte)0xDB,(byte)0x27,(byte)0xEC,// (byte)0x81,(byte)0x72,(byte)0xD5,(byte)0x89,// (byte)0x3B,(byte)0xE0,(byte)0x28,(byte)0xF4,// }; byte plaintAgain[] = rl.multiChunksDe(encryptR); String reS = new String(plaintAgain); System.out.println("restore: " + reS); }catch(Exception e){} } public byte[] multiChunksEn(byte plain[]){ byte []groupData = new byte[16]; byte []encrypt = new byte[16]; int groupNum = plain.length/16+(plain.length%16==0?0:1); byte []encryptR = new byte[groupNum*16]; for(int a=0;a<groupNum;a++){ for(int b=0;b<groupData.length;b++){ if(a*16+b >= plain.length) break; groupData[b] = plain[a*16+b]; } for (int c = 0; c < groupData.length; c++) { System.out.print(groupData[c] + " "); } System.out.println(""); encrypt(groupData, encrypt); for(int b=0;b<encrypt.length;b++){ if(a*16+b >= encryptR.length) break; encryptR[a*16+b] = encrypt[b]; } } return encryptR; } public byte[] multiChunksDe(byte encrypt[]){ byte []groupData = new byte[16]; byte []plaint = new byte[16]; int groupNum = encrypt.length/16+(encrypt.length%16==0?0:1); byte []plainR = new byte[groupNum*16]; for(int a=0;a<groupNum;a++){ for(int b=0;b<groupData.length;b++){ if(a*16+b >= encrypt.length) break; groupData[b] = encrypt[a*16+b]; } decrypt(groupData, plaint); for(int b=0;b<plaint.length;b++){ if(a*16+b >= plainR.length) break; plainR[a*16+b] = plaint[b]; } } return plainR; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -