📄 rijndael.java
字号:
/*
* 所有的字符串作为输入时.
* ***********************************************************
* 在加密和解密的初始阶段,输入数组 in 按照下述规则复制到状态矩阵中: s[r,c]=in[r+4c]
* for 0 ≤ r < 4 且 0 ≤ c < Nb
* 在加密和解密的结束阶段,状态矩阵将按照下述规则被复制到输出数组 out 中: out[r+4c]=
* s[r,c] for 0 ≤ r < 4 且 0 ≤ c < Nb
*/
public class Rijndael {
/* 状态包含的列(32-bit 字)的个数。对于AES,分组输入为128bit时,Nb=4 */
private final int Nb = 4;
private String input = "";
private String state = "";
public Rijndael() {
}
public Rijndael(String state) {
this.state = state;
this.input = state;
}
/**
* 字节变换,将一串输入通过SBox变换输出.
* @param input
* type : 16Byte String .
* @return state .type : 16Byte String .
*/
public String subBytes(String input) {
Operator op = new Operator();
this.state = subBytes(op.ToByte(input));
return this.state;
}
public String invSubBytes(String input) {
Operator op = new Operator();
this.state = invSubBytes(op.ToByte(input));
return this.state;
}
public String invSubBytes(byte[] input) {
SBox sBox = new SBox();
int length = input.length;
String Tstate = "";
for (int i = 0; i < length; i++) {
Tstate += (char) sBox.invSubByte((byte) input[i]);
}
return Tstate;
}
/**
* 字节变换,将一串输入通过SBox变换输出.
* @param input
* type : Byte[16]
* @return state .type : 16Byte String .
*/
public String subBytes(byte[] input) {
SBox sBox = new SBox();
int length = input.length;
String Tstate = "";
for (int i = 0; i < length; i++) {
Tstate += (char) sBox.subByte((byte) input[i]);
}
return Tstate;
}
/**
* 行移位.将16个字符看成4个字节为一列顺序,组成的4*4的矩阵. *
* 将输入的矩阵的每行按行号(from 0)大小进行循环左移.
* @param input
* @return state .type : 16Byte String .
*/
public String shiftRows(String input) {
this.state = "";
byte[][] inputMatrix = new byte[4][Nb];
byte[][] stateMatrix = new byte[4][Nb];
stringToMatrix(input, inputMatrix);// 将字符串的输入,放入一个矩阵.
/*
* 先按行操作.对输入矩阵进行操作,并复制给状态矩阵.****************
* 将行中的4个字节,按行号(from 0)大小进行循环左移
*/
for (int r = 0; r < 4; r++) {
// 行序
for (int c = 0; c < Nb; c++) {
// 列序
stateMatrix[r][c] = inputMatrix[r][(c + r) % Nb];
}
}
matrixToString(stateMatrix);// 将状态矩阵输入到字符串.
/*
* 置空,让JRE自动处理内存. inputMatrix = null; stateMatrix =
* null;
*/
return this.state;
}
/**
* 逆算行移位.将16个字符看成4个字节为一列顺序,组成的4*4的矩阵. *
* 将输入的矩阵的每行按行号(from 3 to 0)大小进行循环右移.
* @param input
* @return state .type : 16Byte String .
*/
public String invShiftRows(String input) {
this.state = "";
byte[][] inputMatrix = new byte[4][Nb];
byte[][] stateMatrix = new byte[4][Nb];
stringToMatrix(input, inputMatrix);// 将字符串的输入,放入一个矩阵.
/*
* 先按行操作.对输入矩阵进行操作,并复制给状态矩阵.****************
* 将行中的4个字节,按行号(from 3 to 0)大小进行循环右移
*/
for (int r = 0; r < 4; r++) {
// 行序
for (int c = 0; c < Nb; c++) {
// 列序
stateMatrix[r][c] = inputMatrix[r][(c - (r + 1) + Nb) % Nb];
}
}
matrixToString(stateMatrix);// 将状态矩阵输入到字符串.
/*
* 置空,让JRE自动处理内存. inputMatrix = null; stateMatrix =
* null;
*/
return this.state;
}
/**
* 将状态矩阵输入到字符串.以每列为单位.
* @param matrix
*/
private void matrixToString(byte[][] matrix) {
/* 先按列操作. 将状态矩阵的元素赋给字符串. */
for (int c = 0; c < Nb; c++) {
// 列序
for (int r = 0; r < 4; r++) {
// 行序
this.state += (char) matrix[r][c];
}
}
}
/**
* 将字符串的输入,放入一个矩阵. 每4字节为单位先按每列进行放.
* @param input
* @param matrix
*/
private void stringToMatrix(String input, byte[][] matrix) {
/* 按每列操作. 将字符串放放输入矩阵 */
for (int c = 0; c < Nb; c++) {
// 列序
for (int r = 0; r < 4; r++) {
// 行序
matrix[r][c] = (byte) input.charAt(r + c * 4);
}
}
}
/**
* 列混合.Hex {03,01,01,02}在行上按行号+1,即(1~4)循环右移.***
* 相乘,按GF(2^8次)Mod.得到状态矩阵.***********************
* GF(8)=x^8+ x^4+x^3+x^1+1,Binary : 1 0001 1011.*
* GF(8)= 11B(16进制.).
* @param input
* type : String
* @return state .type : 16Byte String .
*/
public String mixColumns(String input) {
this.state = "";
byte[][] aMatrix = new byte[4][4];// AES中定义的a(x).
byte[] temp = { (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0x02 };
/*
* 循环右移. 移位个数:1~4 , 赋给a(x)
*/
for (int r = 0; r < 4; r++) {
// 行序
for (int c = 0; c < Nb; c++) {
// 列序
aMatrix[r][c] = temp[(c - (r + 1) + Nb) % Nb];
// System.out.print((byte)aMatrix[r][c] + " ");
}
// System.out.println();
}
byte[][] inputMatrix = new byte[4][Nb];
stringToMatrix(input, inputMatrix);// 赋给状态矩阵
Operator op = new Operator();
byte[][] stateMatrix = new byte[4][Nb];
for (int r = 0; r < Nb; r++) {
for (int m = 0; m < 4; m++) {
for (int q = 0; q < 4; q++) {
stateMatrix[m][r] ^=
op.mulByTwoPolynomials(aMatrix[m][q], inputMatrix[q][r]);
}
}
}
this.matrixToString(stateMatrix);// 将矩阵赋给字符串.
return this.state;
}
/**
* 逆算列混合.Hex
* {0x0b,0x0d,0x09,0x0e}在行上按行号+1,即(1~4)循环右移.
* 相乘,按GF(2^8次)Mod.得到状态矩阵.***********************
* GF(8)=x^8+ x^4+x^3+x^1+1,Binary : 1 0001 1011.*
* GF(8)= 11B(16进制.).
* @param input
* type : String
* @return state .type : 16Byte String .
*/
public String invMixColumns(String input) {
this.state = "";
byte[][] aMatrix = new byte[4][4];// AES中定义的a(x).
byte[] temp = { (byte) 0x0b, (byte) 0x0d, (byte) 0x09, (byte) 0x0e };
/*
* 循环右移. 移位个数:1~4 , 赋给a(x)
*/
for (int r = 0; r < 4; r++) {
// 行序
for (int c = 0; c < Nb; c++) {
// 列序
aMatrix[r][c] = temp[(c - (r + 1) + Nb) % Nb];
// System.out.print((byte)aMatrix[r][c] + " ");
}
// System.out.println();
}
byte[][] inputMatrix = new byte[4][Nb];
stringToMatrix(input, inputMatrix);// 赋给状态矩阵
Operator g = new Operator();
byte[][] stateMatrix = new byte[4][Nb];
for (int r = 0; r < Nb; r++) {
for (int m = 0; m < 4; m++) {
for (int q = 0; q < 4; q++) {
stateMatrix[m][r] ^=
g.mulByTwoPolynomials(aMatrix[m][q], inputMatrix[q][r]);
}
}
}
this.matrixToString(stateMatrix);// 将矩阵赋给字符串.
return this.state;
}
/**
* 加入轮密钥.
* @param input
* type : String
* @return state .type : 16Byte String .
*/
public String addRoundKey(String input, String key) {
String mw = "";
Operator g = new Operator();
int keyc = key.length() / 4;
byte[][] w = new byte[keyc][4];
byte[][] k = new byte[keyc][4];
g.ToByte(w, input);
g.ToByte(k, key);
for (int i = 0; i < keyc; i++) {
w[i] = g.XOR(w[i], k[i]);
mw += g.ToString(w[i]);
}
// System.out.println(mw);
return mw;
}
/**
* rijndael算法.合并了四步.
* @param input
* @return state .type : 16Byte String .
*/
public String rijndael(String input, String key) {
this.state = addRoundKey(input, key);
Key K = new Key();
for (int i = 1; i <= 10; i++) {
key = K.SKey(key, i);
this.state = subBytes(this.state);
this.state = shiftRows(this.state);
if (i < 10) {
this.state = mixColumns(this.state);
}
this.state = addRoundKey(this.state, key);
}
return this.state;
}
public static void main(String[] args) {
Rijndael r = new Rijndael();
String input = "";
String key = "";
byte[] input1 =
{ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, (byte) 0x88,
(byte) 0x99, (byte) 0xaa, (byte) 0xbb, (byte) 0xcc, (byte) 0xdd,
(byte) 0xee, (byte) 0xff };
byte[] key1 =
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
0x0c, 0x0d, 0x0e, 0x0f };
for (int i = 0; i <= 15; i++) {
input += (char) input1[i];
key += (char) key1[i];
}
String z = r.rijndael(input, key);
System.out.println(z);
for (int i = 0; i < z.length(); i++) {
byte MN = (byte) z.charAt(i);
System.out.print(Integer.toHexString(MN) + "****");
}
}
public String getState() {
return state;
}
private void setState(String state) {
this.state = state;
}
public String getInput() {
return input;
}
public void setInput(String input) {
this.input = input;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -