walaupun algoritma ini sudah lapuk alias sudah lama tetapi bagi para kaum pelajar atau mahasiswa tingkat akhir algoritma ini mash layak untuk dipelajari, siapa tau setelah memahami algoritma ini kita bisa membuat kesimpulan atau berinovasi untuk membuat sistem keamanan yang jauh lebih baik lagi,,
berikut adalah source code algoritma aes secara lengkap,,, !!!
/**
* Rijndael.java
*
* @version 1.0 (May 2001)
*
* Optimised Java implementation of the Rijndael (AES) block cipher.
*
* @author Paulo Barreto
*
* This software is hereby placed in the public domain.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
public final class Rijndael {
public Rijndael() {
}
/**
* Flag to setup the encryption key schedule.
*/
public static final int DIR_ENCRYPT = 1;
/**
* Flag to setup the decryption key schedule.
*/
public static final int DIR_DECRYPT = 2;
/**
* Flag to setup both key schedules (encryption/decryption).
*/
public static final int DIR_BOTH = (DIR_ENCRYPT|DIR_DECRYPT);
/**
* AES block size in bits
* (N.B. the Rijndael algorithm itself allows for other sizes).
*/
public static final int BLOCK_BITS = 128;
/**
* AES block size in bytes
* (N.B. the Rijndael algorithm itself allows for other sizes).
*/
public static final int BLOCK_SIZE = (BLOCK_BITS >>> 3);
/**
* Substitution table (S-box).
*/
private static final String SS =
"\u637C\u777B\uF26B\u6FC5\u3001\u672B\uFED7\uAB76" +
"\uCA82\uC97D\uFA59\u47F0\uADD4\uA2AF\u9CA4\u72C0" +
"\uB7FD\u9326\u363F\uF7CC\u34A5\uE5F1\u71D8\u3115" +
"\u04C7\u23C3\u1896\u059A\u0712\u80E2\uEB27\uB275" +
"\u0983\u2C1A\u1B6E\u5AA0\u523B\uD6B3\u29E3\u2F84" +
"\u53D1\u00ED\u20FC\uB15B\u6ACB\uBE39\u4A4C\u58CF" +
"\uD0EF\uAAFB\u434D\u3385\u45F9\u027F\u503C\u9FA8" +
"\u51A3\u408F\u929D\u38F5\uBCB6\uDA21\u10FF\uF3D2" +
"\uCD0C\u13EC\u5F97\u4417\uC4A7\u7E3D\u645D\u1973" +
"\u6081\u4FDC\u222A\u9088\u46EE\uB814\uDE5E\u0BDB" +
"\uE032\u3A0A\u4906\u245C\uC2D3\uAC62\u9195\uE479" +
"\uE7C8\u376D\u8DD5\u4EA9\u6C56\uF4EA\u657A\uAE08" +
"\uBA78\u252E\u1CA6\uB4C6\uE8DD\u741F\u4BBD\u8B8A" +
"\u703E\uB566\u4803\uF60E\u6135\u57B9\u86C1\u1D9E" +
"\uE1F8\u9811\u69D9\u8E94\u9B1E\u87E9\uCE55\u28DF" +
"\u8CA1\u890D\uBFE6\u4268\u4199\u2D0F\uB054\uBB16";
private static final byte[]
Se = new byte[256];
private static final int[]
Te0 = new int[256],
Te1 = new int[256],
Te2 = new int[256],
Te3 = new int[256];
private static final byte[]
Sd = new byte[256];
private static final int[]
Td0 = new int[256],
Td1 = new int[256],
Td2 = new int[256],
Td3 = new int[256];
/**
* Round constants
*/
private static final int[]
rcon = new int[10]; /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
/**
* Number of rounds (depends on key size).
*/
private int Nr = 0;
private int Nk = 0;
private int Nw = 0;
/**
* Encryption key schedule
*/
private int rek[] = null;
/**
* Decryption key schedule
*/
private int rdk[] = null;
static {
/*
Te0[x] = Se[x].[02, 01, 01, 03];
Te1[x] = Se[x].[03, 02, 01, 01];
Te2[x] = Se[x].[01, 03, 02, 01];
Te3[x] = Se[x].[01, 01, 03, 02];
Td0[x] = Sd[x].[0e, 09, 0d, 0b];
Td1[x] = Sd[x].[0b, 0e, 09, 0d];
Td2[x] = Sd[x].[0d, 0b, 0e, 09];
Td3[x] = Sd[x].[09, 0d, 0b, 0e];
*/
int ROOT = 0x11B;
int s1, s2, s3, i1, i2, i4, i8, i9, ib, id, ie, t;
for (i1 = 0; i1 < 256; i1++) {
char c = SS.charAt(i1 >>> 1);
s1 = (byte)((i1 & 1) == 0 ? c >>> 8 : c) & 0xff;
s2 = s1 << 1;
if (s2 >= 0x100) {
s2 ^= ROOT;
}
s3 = s2 ^ s1;
i2 = i1 << 1;
if (i2 >= 0x100) {
i2 ^= ROOT;
}
i4 = i2 << 1;
if (i4 >= 0x100) {
i4 ^= ROOT;
}
i8 = i4 << 1;
if (i8 >= 0x100) {
i8 ^= ROOT;
}
i9 = i8 ^ i1;
ib = i9 ^ i2;
id = i9 ^ i4;
ie = i8 ^ i4 ^ i2;
Se[i1] = (byte)s1;
Te0[i1] = t = (s2 << 24) | (s1 << 16) | (s1 << 8) | s3;
Te1[i1] = (t >>> 8) | (t << 24);
Te2[i1] = (t >>> 16) | (t << 16);
Te3[i1] = (t >>> 24) | (t << 8);
Sd[s1] = (byte)i1;
Td0[s1] = t = (ie << 24) | (i9 << 16) | (id << 8) | ib;
Td1[s1] = (t >>> 8) | (t << 24);
Td2[s1] = (t >>> 16) | (t << 16);
Td3[s1] = (t >>> 24) | (t << 8);
}
/*
* round constants
*/
int r = 1;
rcon[0] = r << 24;
for (int i = 1; i < 10; i++) {
r <<= 1;
if (r >= 0x100) {
r ^= ROOT;
}
rcon[i] = r << 24;
}
}
/**
* Expand a cipher key into a full encryption key schedule.
*
* @param cipherKey the cipher key (128, 192, or 256 bits).
*/
private void expandKey(byte[] cipherKey) {
int temp, r = 0;
for (int i = 0, k = 0; i < Nk; i++, k += 4) {
rek[i] =
((cipherKey[k ] ) << 24) |
((cipherKey[k + 1] & 0xff) << 16) |
((cipherKey[k + 2] & 0xff) << 8) |
((cipherKey[k + 3] & 0xff));
}
for (int i = Nk, n = 0; i < Nw; i++, n--) {
temp = rek[i - 1];
if (n == 0) {
n = Nk;
temp =
((Se[(temp >>> 16) & 0xff] ) << 24) |
((Se[(temp >>> 8) & 0xff] & 0xff) << 16) |
((Se[(temp ) & 0xff] & 0xff) << 8) |
((Se[(temp >>> 24) ] & 0xff));
temp ^= rcon[r++];
} else if (Nk == 8 && n == 4) {
temp =
((Se[(temp >>> 24) ] ) << 24) |
((Se[(temp >>> 16) & 0xff] & 0xff) << 16) |
((Se[(temp >>> 8) & 0xff] & 0xff) << 8) |
((Se[(temp ) & 0xff] & 0xff));
}
rek[i] = rek[i - Nk] ^ temp;
}
temp = 0;
}
/*
* Faster implementation of the key expansion
* (only worthwhile in Rijndael is used in a hashing function mode).
*/
/*
private void expandKey(byte[] cipherKey) {
int keyOffset = 0;
int i = 0;
int temp;
rek[0] =
(cipherKey[ 0] ) << 24 |
(cipherKey[ 1] & 0xff) << 16 |
(cipherKey[ 2] & 0xff) << 8 |
(cipherKey[ 3] & 0xff);
rek[1] =
(cipherKey[ 4] ) << 24 |
(cipherKey[ 5] & 0xff) << 16 |
(cipherKey[ 6] & 0xff) << 8 |
(cipherKey[ 7] & 0xff);
rek[2] =
(cipherKey[ 8] ) << 24 |
(cipherKey[ 9] & 0xff) << 16 |
(cipherKey[10] & 0xff) << 8 |
(cipherKey[11] & 0xff);
rek[3] =
(cipherKey[12] ) << 24 |
(cipherKey[13] & 0xff) << 16 |
(cipherKey[14] & 0xff) << 8 |
(cipherKey[15] & 0xff);
if (Nk == 4) {
for (;;) {
temp = rek[keyOffset + 3];
rek[keyOffset + 4] = rek[keyOffset] ^
((Se[(temp >>> 16) & 0xff] ) << 24) ^
((Se[(temp >>> 8) & 0xff] & 0xff) << 16) ^
((Se[(temp ) & 0xff] & 0xff) << 8) ^
((Se[(temp >>> 24) ] & 0xff) ) ^
rcon[i];
rek[keyOffset + 5] = rek[keyOffset + 1] ^ rek[keyOffset + 4];
rek[keyOffset + 6] = rek[keyOffset + 2] ^ rek[keyOffset + 5];
rek[keyOffset + 7] = rek[keyOffset + 3] ^ rek[keyOffset + 6];
if (++i == 10) {
return;
}
keyOffset += 4;
}
}
rek[keyOffset + 4] =
(cipherKey[16] ) << 24 |
(cipherKey[17] & 0xff) << 16 |
(cipherKey[18] & 0xff) << 8 |
(cipherKey[19] & 0xff);
rek[keyOffset + 5] =
(cipherKey[20] ) << 24 |
(cipherKey[21] & 0xff) << 16 |
(cipherKey[22] & 0xff) << 8 |
(cipherKey[23] & 0xff);
if (Nk == 6) {
for (;;) {
temp = rek[keyOffset + 5];
rek[keyOffset + 6] = rek[keyOffset] ^
((Se[(temp >>> 16) & 0xff] ) << 24) ^
((Se[(temp >>> 8) & 0xff] & 0xff) << 16) ^
((Se[(temp ) & 0xff] & 0xff) << 8) ^
((Se[(temp >>> 24) ] & 0xff) ) ^
rcon[i];
rek[keyOffset + 7] = rek[keyOffset + 1] ^ rek[keyOffset + 6];
rek[keyOffset + 8] = rek[keyOffset + 2] ^ rek[keyOffset + 7];
rek[keyOffset + 9] = rek[keyOffset + 3] ^ rek[keyOffset + 8];
if (++i == 8) {
return;
}
rek[keyOffset + 10] = rek[keyOffset + 4] ^ rek[keyOffset + 9];
rek[keyOffset + 11] = rek[keyOffset + 5] ^ rek[keyOffset + 10];
keyOffset += 6;
}
}
rek[keyOffset + 6] =
(cipherKey[24] ) << 24 |
(cipherKey[25] & 0xff) << 16 |
(cipherKey[26] & 0xff) << 8 |
(cipherKey[27] & 0xff);
rek[keyOffset + 7] =
(cipherKey[28] ) << 24 |
(cipherKey[29] & 0xff) << 16 |
(cipherKey[30] & 0xff) << 8 |
(cipherKey[31] & 0xff);
if (Nk == 8) {
for (;;) {
temp = rek[keyOffset + 7];
rek[keyOffset + 8] = rek[keyOffset] ^
((Se[(temp >>> 16) & 0xff] ) << 24) ^
((Se[(temp >>> 8) & 0xff] & 0xff) << 16) ^
((Se[(temp ) & 0xff] & 0xff) << 8) ^
((Se[(temp >>> 24) ] & 0xff) ) ^
rcon[i];
rek[keyOffset + 9] = rek[keyOffset + 1] ^ rek[keyOffset + 8];
rek[keyOffset + 10] = rek[keyOffset + 2] ^ rek[keyOffset + 9];
rek[keyOffset + 11] = rek[keyOffset + 3] ^ rek[keyOffset + 10];
if (++i == 7) {
return;
}
temp = rek[keyOffset + 11];
rek[keyOffset + 12] = rek[keyOffset + 4] ^
((Se[(temp >>> 24) ] ) << 24) ^
((Se[(temp >>> 16) & 0xff] & 0xff) << 16) ^
((Se[(temp >>> 8) & 0xff] & 0xff) << 8) ^
((Se[(temp ) & 0xff] & 0xff));
rek[keyOffset + 13] = rek[keyOffset + 5] ^ rek[keyOffset + 12];
rek[keyOffset + 14] = rek[keyOffset + 6] ^ rek[keyOffset + 13];
rek[keyOffset + 15] = rek[keyOffset + 7] ^ rek[keyOffset + 14];
keyOffset += 8;
}
}
}
*/
/**
* Compute the decryption schedule from the encryption schedule .
*/
private void invertKey() {
int d = 0, e = 4*Nr, w;
/*
* apply the inverse MixColumn transform to all round keys
* but the first and the last:
*/
rdk[d ] = rek[e ];
rdk[d + 1] = rek[e + 1];
rdk[d + 2] = rek[e + 2];
rdk[d + 3] = rek[e + 3];
d += 4;
e -= 4;
for (int r = 1; r < Nr; r++) {
w = rek[e ];
rdk[d ] =
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 + 1];
rdk[d + 1] =
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 + 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;
}
}
}
Semoga Bermanfaat
Refferensi : http://www.cs.ucdavis.edu/~rogaway/ocb/ocb-java/Rijndael.java