📄 aes_encrypt.java
字号:
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);
}
}
// encrypt/decrypt columns of the key
// n.b. you can replace this with
// byte-wise xor if you wish.
void AddRoundKey (char state[], char key[])
{
int idx;
for( idx = 0; idx <16; idx++ ) //把idx < 4改为idx < 16
state[idx] ^= key[idx];
}
static void AddRoundKey(char[] state, char[] expkey, int key) {
int idx;
for (idx = 0; idx < 16; idx++) {
state[idx] ^= expkey[key + idx];
}
}
// encrypt one 128 bit block
byte[] Encrypt (char in[], char expkey[])
{
char[] out=new char[16];
int round, idx,i=0;
char[] state=new char[Nb * 4]; //自加注释:state[16]
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++];
}
AddRoundKey (state, expkey);
// AddRoundKey (state, expkey,160);
for( round = 1; round < Nr + 1; round++ ) {
if( round < Nr )
MixSubColumns (state);
else
ShiftRows (state);//最后一轮不需要列混淆
// AddRoundKey (state, expkey + round * Nb); //把round * Nb改为round * 16
AddRoundKey(state, expkey, round * 16);
}
int ii=0;
for( idx = 0; idx < Nb; idx++ ) {
out[ii++] = state[4*idx+0];
out[ii++] = state[4*idx+1];
out[ii++] = state[4*idx+2];
out[ii++] = state[4*idx+3];
}
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;
}
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;
}
/**
* 加密16字节的数组
* @param in byte[] 输入字节数,必须大小不能大于16
* @param key char[] 密钥
* @return byte[] 输出字节数,必须大小不能大于16
*/
public byte[] Encrypt_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 = Encrypt(ByteToChar(in), expkey); //解密变换;
} catch (Exception e) {
System.out.println("hello");
e.printStackTrace();
}
return out;
}
/**
* 文件加密,文件长度不能被16整除的,在文件的开头加‘A’,标示:02AAAAAAAAA
* @param Encrypt_Befor String 源文件路径
* @param Encrypt_After String 目标文件路径
* @param Key String 密钥字符串,必须是16位
* @throws Exception
*/
public void Encrypt_File(String Encrypt_Befor, String Encrypt_After,String Key) throws Exception {
if(Key==null||Key.length()>16){
System.out.println("你的密钥为空或者太长--程序退出");
return;
}
char[] key=Key.toCharArray();
long startTime = System.nanoTime();
//char[] key = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n','o', 'p'};
byte[] copy = new byte[16];
char[] expkey = new char[4 * Nb * (Nr + 1)];
FileInputStream fp1 = new FileInputStream(Encrypt_Befor);
FileOutputStream fp2 = new FileOutputStream(Encrypt_After, true);
long Length = fp1.available(); //得到文件长度
long N = 0;
if (Length != 0) {
N = 18 - (Length + 2) % 16; //补0个个数为N-2
if (N == 18)
N = 2;
}
Length = Length + N;
long leave = Length / (4 * Nb); //得到整块的加密轮数;
byte[] state = new byte[16];
boolean isnull = true;
boolean indexout = false;
byte[] bb = new byte[14];
int first=1;
while (leave > 0) { //分组长度的整数倍的密文块解密;, for(int g=0;g<16;g++)
if (first == 1) {
state[0] = (byte) (N / 10);
state[1] = (byte) (N % 10);
for (int j = 2; j < N; j++) {
state[j] = 'A';
}
try {
fp1.read(state, (int) (N), (int) (16 - N)); //读取密文块;
} catch (IOException ex) {
ex.printStackTrace();
}
first = 2;
} else {
fp1.read(state, 0, 16); //读取密文块;
}
ExpandKey(key, expkey);
try {
copy = Encrypt(ByteToChar(state), expkey); //解密变换;
}
catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
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 + -