四.Rijndael算法实现,java版本
public class Rijndael_Algorithms {
private byte[] key;
/**-------------------- Rijndael round subkeys ---------------------*/
private byte roundKeys[][][] = new byte[11][4][4];
/**
* -------------------------------------------------------------------
* Rijndael key schedule function. Takes 16-byte key and creates
* all Rijndael's internal subkeys ready for encryption.
* -----------------------------------------------------------------
*/
public Rijndael_Algorithms(byte[] key) {
this.key = key;
RijndaelKeySchedule();
}
public void RijndaelKeySchedule()
{
byte roundConst;
int i, j;
// first round key equals key
for (i = 0; i < 16; i++) {
roundKeys[0][i & 0x03][i >> 2] = key[i];
}
roundConst = 1;
// now calculate round keys */
for (i = 1; i < 11; i++) {
roundKeys[i][0][0] = (byte) (S[byteToU8(roundKeys[i - 1][1][3])]
^ roundKeys[i - 1][0][0] ^ roundConst);
roundKeys[i][1][0] = (byte) (S[byteToU8(roundKeys[i - 1][2][3])] ^ roundKeys[i - 1][1][0]);
roundKeys[i][2][0] = (byte) (S[byteToU8(roundKeys[i - 1][3][3])] ^ roundKeys[i - 1][2][0]);
roundKeys[i][3][0] = (byte) (S[byteToU8(roundKeys[i - 1][0][3])] ^ roundKeys[i - 1][3][0]);
for (j = 0; j < 4; j++) {
roundKeys[i][j][1] = (byte) (roundKeys[i - 1][j][1] ^ roundKeys[i][j][0]);
roundKeys[i][j][2] = (byte) (roundKeys[i - 1][j][2] ^ roundKeys[i][j][1]);
roundKeys[i][j][3] = (byte) (roundKeys[i - 1][j][3] ^ roundKeys[i][j][2]);
}
// update round constant */
roundConst = Xtime[byteToU8(roundConst)];
}
}
/**
* -------------------------------------------------------------------
* Rijndael encryption function. Takes 16-byte input and creates
* 16-byte output (using round keys already derived from 16-byte
* key).
* -----------------------------------------------------------------
*/
public byte[] rijndaelEncrypt(byte[] input) {
byte[][] state = new byte[4][4];
int i, r;
// initialise state array from input byte string
for (i = 0; i < 16; i++) {
state[i & 0x3][i >> 2] = input[i];
}
// add first round_key
keyAdd(state, roundKeys, 0);
// do lots of full rounds
for (r = 1; r <= 9; r++) {
byteSub(state);
shiftRow(state);
mixColumn(state);
keyAdd(state, roundKeys, r);
}
// final round
byteSub(state);
shiftRow(state);
keyAdd(state, roundKeys, r);
// produce output byte string from state array
byte[] output = new byte[16];
for (i = 0; i < 16; i++) {
output[i] = state[i & 0x3][i >> 2];
}
return output;
}
/**
* -------------------------------------------------------------------
* Rijndael decryption function. Takes 16-byte input and creates
* 16-byte output (using round keys already derived from 16-byte
* key).
* -----------------------------------------------------------------
*/
public byte[] rijndaelDecrypt(byte[] input)
{
//TODO
return null;
}
/**
* Round key addition function
* @param state[4][4]
* @param roundKeys[11][4][4]
* @param int
*/
private void keyAdd(byte[][] state, byte[][][] roundKeys, int round)
{
int i, j;
for (i=0; i<4; i++)
for (j=0; j<4; j++)
state[i][j] ^= roundKeys[round][i][j];
return;
}
/**
* Byte substitution transformation
* @param state[4][4]
*/
private int byteSub(byte[][] state)
{
int i, j;
for (i=0; i<4; i++)
for (j=0; j<4; j++)
state[i][j] = S[byteToU8(state[i][j])];
return 0;
}
/**
* Row shift transformation
* @param state[4][4]
*
*/
private static void shiftRow(byte[][] state)
{
byte temp;
/* left rotate row 1 by 1 */
temp = state[1][0];
state[1][0] = state[1][1];
state[1][1] = state[1][2];
state[1][2] = state[1][3];
state[1][3] = temp;
/* left rotate row 2 by 2 */
temp = state[2][0];
state[2][0] = state[2][2];
state[2][2] = temp;
temp = state[2][1];
state[2][1] = state[2][3];
state[2][3] = temp;
/* left rotate row 3 by 3 */
temp = state[3][0];
state[3][0] = state[3][3];
state[3][3] = state[3][2];
state[3][2] = state[3][1];
state[3][1] = temp;
return;
}
/**
* MixColumn transformation
* @param state[4][4]
*/
private void mixColumn(byte[][] state)
{
byte temp, tmp, tmp0;
int i;
/* do one column at a time */
for (i=0; i<4;i++)
{
temp = (byte) (state[0][i] ^ state[1][i] ^ state[2][i] ^ state[3][i]);
tmp0 = state[0][i];
/* Xtime array does multiply by x in GF2^8 */
tmp = Xtime[byteToU8(state[0][i] ^ state[1][i])];
state[0][i] ^= temp ^ tmp;
tmp = Xtime[byteToU8(state[1][i] ^ state[2][i])];
state[1][i] ^= temp ^ tmp;
tmp = Xtime[byteToU8(state[2][i] ^ state[3][i])];
state[2][i] ^= temp ^ tmp;
tmp = Xtime[byteToU8(state[3][i] ^ tmp0)];
state[3][i] ^= temp ^ tmp;
}
return;
}
/**
* byte to u8
* java的byte存在小于0的情况,转化为无符号数
* @param b
* @return
*/
private static int byteToU8(int b)
{
return b < 0 ? b + 256 : b ;
}
/**--------------------- Rijndael S box table ----------------------*/
private static byte S[] = { 99, 124, 119, 123, (byte) 242, 107, 111, (byte) 197, 48, 1,
103, 43, (byte) 254, (byte) 215, (byte) 171, 118, (byte) 202,
(byte) 130, (byte) 201, 125, (byte) 250, 89, 71, (byte) 240,
(byte) 173, (byte) 212, (byte) 162, (byte) 175, (byte) 156,
(byte) 164, 114, (byte) 192, (byte) 183, (byte) 253, (byte) 147,
38, 54, 63, (byte) 247, (byte) 204, 52, (byte) 165, (byte) 229,
(byte) 241, 113, (byte) 216, 49, 21, 4, (byte) 199, 35, (byte) 195,
24, (byte) 150, 5, (byte) 154, 7, 18, (byte) 128, (byte) 226,
(byte) 235, 39, (byte) 178, 117, 9, (byte) 131, 44, 26, 27, 110,
90, (byte) 160, 82, 59, (byte) 214, (byte) 179, 41, (byte) 227, 47,
(byte) 132, 83, (byte) 209, 0, (byte) 237, 32, (byte) 252,
(byte) 177, 91, 106, (byte) 203, (byte) 190, 57, 74, 76, 88,
(byte) 207, (byte) 208, (byte) 239, (byte) 170, (byte) 251, 67, 77,
51, (byte) 133, 69, (byte) 249, 2, 127, 80, 60, (byte) 159,
(byte) 168, 81, (byte) 163, 64, (byte) 143, (byte) 146, (byte) 157,
56, (byte) 245, (byte) 188, (byte) 182, (byte) 218, 33, 16,
(byte) 255, (byte) 243, (byte) 210, (byte) 205, 12, 19, (byte) 236,
95, (byte) 151, 68, 23, (byte) 196, (byte) 167, 126, 61, 100, 93,
25, 115, 96, (byte) 129, 79, (byte) 220, 34, 42, (byte) 144,
(byte) 136, 70, (byte) 238, (byte) 184, 20, (byte) 222, 94, 11,
(byte) 219, (byte) 224, 50, 58, 10, 73, 6, 36, 92, (byte) 194,
(byte) 211, (byte) 172, 98, (byte) 145, (byte) 149, (byte) 228,
121, (byte) 231, (byte) 200, 55, 109, (byte) 141, (byte) 213, 78,
(byte) 169, 108, 86, (byte) 244, (byte) 234, 101, 122, (byte) 174,
8, (byte) 186, 120, 37, 46, 28, (byte) 166, (byte) 180, (byte) 198,
(byte) 232, (byte) 221, 116, 31, 75, (byte) 189, (byte) 139,
(byte) 138, 112, 62, (byte) 181, 102, 72, 3, (byte) 246, 14, 97,
53, 87, (byte) 185, (byte) 134, (byte) 193, 29, (byte) 158,
(byte) 225, (byte) 248, (byte) 152, 17, 105, (byte) 217,
(byte) 142, (byte) 148, (byte) 155, 30, (byte) 135, (byte) 233,
(byte) 206, 85, 40, (byte) 223, (byte) 140, (byte) 161, (byte) 137,
13, (byte) 191, (byte) 230, 66, 104, 65, (byte) 153, 45, 15,
(byte) 176, 84, (byte) 187, 22, };
/**------- This array does the multiplication by x in GF(2^8) ------*/
private static byte Xtime[] = { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30,
32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64,
66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98,
100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124,
126, (byte) 128, (byte) 130, (byte) 132, (byte) 134, (byte) 136,
(byte) 138, (byte) 140, (byte) 142, (byte) 144, (byte) 146,
(byte) 148, (byte) 150, (byte) 152, (byte) 154, (byte) 156,
(byte) 158, (byte) 160, (byte) 162, (byte) 164, (byte) 166,
(byte) 168, (byte) 170, (byte) 172, (byte) 174, (byte) 176,
(byte) 178, (byte) 180, (byte) 182, (byte) 184, (byte) 186,
(byte) 188, (byte) 190, (byte) 192, (byte) 194, (byte) 196,
(byte) 198, (byte) 200, (byte) 202, (byte) 204, (byte) 206,
(byte) 208, (byte) 210, (byte) 212, (byte) 214, (byte) 216,
(byte) 218, (byte) 220, (byte) 222, (byte) 224, (byte) 226,
(byte) 228, (byte) 230, (byte) 232, (byte) 234, (byte) 236,
(byte) 238, (byte) 240, (byte) 242, (byte) 244, (byte) 246,
(byte) 248, (byte) 250, (byte) 252, (byte) 254, 27, 25, 31, 29, 19,
17, 23, 21, 11, 9, 15, 13, 3, 1, 7, 5, 59, 57, 63, 61, 51, 49, 55,
53, 43, 41, 47, 45, 35, 33, 39, 37, 91, 89, 95, 93, 83, 81, 87, 85,
75, 73, 79, 77, 67, 65, 71, 69, 123, 121, 127, 125, 115, 113, 119,
117, 107, 105, 111, 109, 99, 97, 103, 101, (byte) 155, (byte) 153,
(byte) 159, (byte) 157, (byte) 147, (byte) 145, (byte) 151,
(byte) 149, (byte) 139, (byte) 137, (byte) 143, (byte) 141,
(byte) 131, (byte) 129, (byte) 135, (byte) 133, (byte) 187,
(byte) 185, (byte) 191, (byte) 189, (byte) 179, (byte) 177,
(byte) 183, (byte) 181, (byte) 171, (byte) 169, (byte) 175,
(byte) 173, (byte) 163, (byte) 161, (byte) 167, (byte) 165,
(byte) 219, (byte) 217, (byte) 223, (byte) 221, (byte) 211,
(byte) 209, (byte) 215, (byte) 213, (byte) 203, (byte) 201,
(byte) 207, (byte) 205, (byte) 195, (byte) 193, (byte) 199,
(byte) 197, (byte) 251, (byte) 249, (byte) 255, (byte) 253,
(byte) 243, (byte) 241, (byte) 247, (byte) 245, (byte) 235,
(byte) 233, (byte) 239, (byte) 237, (byte) 227, (byte) 225,
(byte) 231, (byte) 229 };
}
参考文档:TS 35.206 后面C++代码改写