📄 aes_decrypt.java
字号:
newstate[10] = (char) (XtimeD[state[0]] ^ Xtime9[state[1]] ^ XtimeE[state[2]] ^
XtimeB[state[3]]);
newstate[15] = (char) (XtimeB[state[0]] ^ XtimeD[state[1]] ^ Xtime9[state[2]] ^
XtimeE[state[3]]);
// restore column 1
newstate[4] = (char) (XtimeE[state[4]] ^ XtimeB[state[5]] ^ XtimeD[state[6]] ^
Xtime9[state[7]]);
newstate[9] = (char) (Xtime9[state[4]] ^ XtimeE[state[5]] ^ XtimeB[state[6]] ^
XtimeD[state[7]]);
newstate[14] = (char) (XtimeD[state[4]] ^ Xtime9[state[5]] ^ XtimeE[state[6]] ^
XtimeB[state[7]]);
newstate[3] = (char) (XtimeB[state[4]] ^ XtimeD[state[5]] ^ Xtime9[state[6]] ^
XtimeE[state[7]]);
// restore column 2
newstate[8] = (char) (XtimeE[state[8]] ^ XtimeB[state[9]] ^ XtimeD[state[10]] ^
Xtime9[state[11]]);
newstate[13] = (char) (Xtime9[state[8]] ^ XtimeE[state[9]] ^
XtimeB[state[10]] ^ XtimeD[state[11]]);
newstate[2] = (char) (XtimeD[state[8]] ^ Xtime9[state[9]] ^ XtimeE[state[10]] ^
XtimeB[state[11]]);
newstate[7] = (char) (XtimeB[state[8]] ^ XtimeD[state[9]] ^ Xtime9[state[10]] ^
XtimeE[state[11]]);
// restore column 3
newstate[12] = (char) (XtimeE[state[12]] ^ XtimeB[state[13]] ^
XtimeD[state[14]] ^ Xtime9[state[15]]);
newstate[1] = (char) (Xtime9[state[12]] ^ XtimeE[state[13]] ^
XtimeB[state[14]] ^ XtimeD[state[15]]);
newstate[6] = (char) (XtimeD[state[12]] ^ Xtime9[state[13]] ^
XtimeE[state[14]] ^ XtimeB[state[15]]);
newstate[11] = (char) (XtimeB[state[12]] ^ XtimeD[state[13]] ^
Xtime9[state[14]] ^ XtimeE[state[15]]);
for (i = 0; i < 4 * Nb; i++) {
state[i] = InvSbox[newstate[i]];
}
}
// encrypt/decrypt columns of the key
// n.b. you can replace this with
// byte-wise xor if you wish.
static char Rcon[] = {
0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36};
// produce Nk bytes for each round
public static void ExpandKey(char[] key, char[] expkey) {
char tmp0, tmp1, tmp2, tmp3, tmp4;
int idx;
for (idx = 0; idx < Nk; idx++) {
expkey[4 * idx + 0] = key[4 * idx + 0];
expkey[4 * idx + 1] = key[4 * idx + 1];
expkey[4 * idx + 2] = key[4 * idx + 2];
expkey[4 * idx + 3] = key[4 * idx + 3];
}
for (idx = Nk; idx < Nb * (Nr + 1); idx++) {
tmp0 = expkey[4 * idx - 4];
tmp1 = expkey[4 * idx - 3];
tmp2 = expkey[4 * idx - 2];
tmp3 = expkey[4 * idx - 1];
if ( (idx % Nk) <= 0) {
tmp4 = tmp3;
tmp3 = Sbox[tmp0];
tmp0 = (char) (Sbox[tmp1] ^ Rcon[idx / Nk]);
tmp1 = Sbox[tmp2];
tmp2 = Sbox[tmp4];
}
// convert from longs to bytes
expkey[4 * idx + 0] = (char) (expkey[4 * idx - 4 * Nk + 0] ^ tmp0);
expkey[4 * idx + 1] = (char) (expkey[4 * idx - 4 * Nk + 1] ^ tmp1);
expkey[4 * idx + 2] = (char) (expkey[4 * idx - 4 * Nk + 2] ^ tmp2);
expkey[4 * idx + 3] = (char) (expkey[4 * idx - 4 * Nk + 3] ^ tmp3);
}
}
static void AddRoundKey(char[] state, char[] expkey, int key) {
int idx;
for (idx = 0; idx < 16; idx++) {
state[idx] ^= expkey[key + idx];
}
}
public static byte[] Decrypt(char[] in, char[] expkey) {
char[] out = new char[16];
int idx, round, j;
char state[] = new char[Nb * 4];
int i = 0;
for (idx = 0; idx < Nb; idx++) {
state[4 * idx + 0] = in[i++];
state[4 * idx + 1] = in[i++];
state[4 * idx + 2] = in[i++];
state[4 * idx + 3] = in[i++];
}
// byte[] a=CharToByte(state);
//System.out.println((int)a[0]);
try {
AddRoundKey(state, expkey, 160); //////////////////////
byte[] b = CharToByte(state);
// System.out.println((int)b[0]+"----------AddRoundKey");
}
catch (Exception e) {
System.out.println("fuck");
}
round = Nr;
try {
InvShiftRows(state);
byte[] c = CharToByte(state);
// System.out.println((int)c[0]+"----------InvShiftRows");
}
catch (Exception e) {
System.out.println("fuck22222");
}
while (round-- > 0) {
AddRoundKey(state, expkey, round * 16); ////////////////////////////
if (round > 0) {
InvMixSubColumns(state);
}
}
// System.out.println((int)state[0]+"----------while");
int n = 0;
for (idx = 0; idx < Nb; idx++) {
out[n++] = state[4 * idx + 0];
out[n++] = state[4 * idx + 1];
out[n++] = state[4 * idx + 2];
out[n++] = state[4 * idx + 3];
}
//for(int d=0;d<out.length;d++)
// System.out.print((int)out[0]);
return CharToByte(out);
}
public static char[] ByteToChar(byte[] data) {
char[] A = new char[data.length];
for (int i = 0; i < data.length; i++) {
A[i] = (char) data[i];
}
return A;
}
/**
* This method is used to transform a array from char type to byte type.
* @param data a char type array.
* @return a byte type array.
*/
public static byte[] CharToByte(char[] data) {
byte[] A = new byte[data.length];
for (int i = 0; i < data.length; i++) {
A[i] = (byte) data[i];
}
return A;
}
/**
* 求出需要删除的多余字节
* @param data byte[]
* @return int
*/
public static int getinsertlen(byte[] data) {
int[] A = new int[2];
for (int i = 0; i < 2; i++) {
A[i] = (int) (char) data[i];
}
int len = A[0] * 10 + A[1];
return len;
}
/**
* 去掉加入的无用字节
* @param data byte[]
* @param len String
* @return byte[]
*/
public static byte[] Bytedelete(byte[] data, int len) {
byte[] A = new byte[16 - len];
for (int i = 0; i < 16 - len; i++) {
A[i] = data[i + len];
}
return A;
}
/**
* 16位字节解密
* @param in byte[] 输入字节数组
* @param key String 密钥
* @return byte[] 返回解密后的数组
*/
public byte[] Decrypt_Byte(byte[] in,String key) {
if(in.length>16||key.length()!=16){
System.out.println("No!! 你输入的字节数或密钥位数大于16,请输入安全的数据,解密程序退出");
System.exit(1);
}
char[] KEY=key.toCharArray();
char[] expkey = new char[4 * Nb * (Nr + 1)];
byte[] out = new byte[16];
ExpandKey(KEY, expkey);
try {
out = Decrypt(ByteToChar(in), expkey); //解密变换;
} catch (Exception e) {
e.printStackTrace();
}
return out;
}
/**
* 解密文件
* @param Encrypt_Befor String 源文件路径
* @param Encrypt_After String 目标文件路径
* @param key String 密钥
* @throws Exception
*/
public void Decrypt_File(String Encrypt_Befor, String Encrypt_After,String key) throws Exception {
if(key==null||key.length()!=16){
System.out.println("你的密钥为空,或不是16位的,程序退出");
return;
}
long startTime = System.nanoTime();
char[] KEY=key.toCharArray();
byte[] copy = new byte[16];
char[] expkey = new char[4 * Nb * (Nr + 1)];
FileInputStream fp1 = new FileInputStream(Encrypt_Befor);
FileOutputStream fp2 = null;
long Length = fp1.available(); //得到文件长度
long leave = Length / (4 * Nb); //得到整块的加密轮数;
byte[] state = new byte[16];
boolean isnull = true;
boolean indexout = false;
byte[] bb = new byte[14];
while (leave > 0) { //分组长度的整数倍的密文块解密;, for(int g=0;g<16;g++)
fp1.read(state, 0, 4 * Nb); //读取密文块;
ExpandKey(KEY, expkey);
try {
copy = Decrypt(ByteToChar(state), expkey); //解密变换;
}
catch (Exception e) {
System.out.println("hello");
e.printStackTrace();
System.exit(1);
}
if (isnull == true) {
if (indexout == false) {
len = getinsertlen(copy);
if (len > 18) {
fp1.close();
throw(new Exception("解密失败"));
}
else {
fp2 = new FileOutputStream(Encrypt_After, true);
}
}
if (len == 18) {
bb = Bytedelete(copy, 1);
fp2.write(bb, 0, 15); //将解密后的明文写入目标文件;
System.out.println("第2次A");
indexout = false;
isnull = false;
}
if (len <= 16) {
bb = Bytedelete(copy, len);
fp2.write(bb, 0, 16 - len); //将解密后的明文写入目标文件;
isnull = false;
}
if (len > 16 && len < 19) {
bb = Bytedelete(copy, 15);
indexout = true;
len = 18;
}
}
else {
fp2.write(copy, 0, 16); //将解密后的明文写入目标文件;
}
leave--; //轮数减一;
}
fp1.close(); //关闭源文件和目标文件;
fp2.close();
long timer = (System.nanoTime() - startTime) / 1000000;
System.out.println("文件大小: ....." + Length);
System.out.println("共需时间: ....." + timer);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -