?? aesencrypt.java
字號:
package myCode.aesCroptography;
public class AesEncrypt {
private static int[] gf28 = {0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80,
0x1B, 0x36, 0x6C, 0xD8, 0xAB, 0x4D, 0x9A};
private static int[] sbox = {0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16};
private static int[] invsbox = {0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D};
private static int[] rc = {0x0, 0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36};
private byte[] key;
private byte[][] keyexpand;
public AesEncrypt() {
this.key = new byte[16];
this.keyexpand = new byte[44][4];
}
public byte[] encrypt (byte[] mess) {
byte[] out = new byte[16];
if (mess.length != 16) {
System.out.println("錯誤:消息不是16位!");
return null;
}
byte[][] state = new byte[4][4];
int m, n;
for (m=0; m<4; m++) {
for (n=0; n<4; n++) {
state[n][m] = mess[m*4+n];
}
}
state = this.keyPlus(state, 0);
for (n=1; n<10; n++) {
state = this.substitute(state);
state = this.horShift(state);
state = this.vertMix(state);
state = this.keyPlus(state, n);
}
state = this.substitute(state);
state = this.horShift(state);
state = this.keyPlus(state, 10);
for (m=0; m<4; m++) {
for (n=0; n<4; n++) {
out[m*4+n] = state[n][m];
}
}
return out;
}
public byte[] decrypt (byte[] enc) {
byte[] out = new byte[16];
if (enc.length != 16) {
System.out.println("錯誤:密文不是16位!");
return null;
}
byte[][] state = new byte[4][4];
int m, n;
for (m=0; m<4; m++) {
for (n=0; n<4; n++) {
state[n][m] = enc[m*4+n];
}
}
state = this.keyPlus(state, 10);
for (n=9; n>0; n--) {
state = this.invHorShift(state);
state = this.invSubstitute(state);
state = this.keyPlus(state, n);
state = this.invVertMix(state);
}
state = this.invHorShift(state);
state = this.invSubstitute(state);
state = this.keyPlus(state, 0);
for (m=0; m<4; m++) {
for (n=0; n<4; n++) {
out[m*4+n] = state[n][m];
}
}
return out;
}
private byte[][] horShift (byte[][] in) {
byte[][] out = new byte[4][4];
int m, n;
for (m=0; m<4; m++) {
for (n=0; n<4; n++) {
out[m][n] = in[m][(n+m) & 0x3];
}
}
return out;
}
private byte[][] invHorShift (byte[][] in) {
byte[][] out = new byte[4][4];
int m, n;
for (m=0; m<4; m++) {
for (n=0; n<4; n++) {
out[m][n] = in[m][(n-m) & 0x3];
}
}
return out;
}
private byte[][] vertMix (byte[][] in) {
byte[][]out = new byte[4][4];
int m;
int temp;
for (m=0; m<4; m++) {
temp = this.GF28X((byte)0x2, in[0][m]);
temp = temp ^ this.GF28X((byte)0x3, in[1][m]);
temp = temp ^ in[2][m];
temp = (temp ^ in[3][m]) & 0xFF;
out[0][m] = (byte) temp;
}
for (m=0; m<4; m++) {
temp = (int) in[0][m];
temp = temp ^ this.GF28X((byte)0x2, in[1][m]);
temp = temp ^ this.GF28X((byte)0x3, in[2][m]);
temp = (temp ^ in[3][m]) & 0xFF;
out[1][m] = (byte) temp;
}
for (m=0; m<4; m++) {
temp = (int) in[0][m];
temp = temp ^ in[1][m];
temp = temp ^ this.GF28X((byte)0x2, in[2][m]);
temp = temp ^ this.GF28X((byte)0x3, in[3][m]);
temp = temp & 0xFF;
out[2][m] = (byte) temp;
}
for (m=0; m<4; m++) {
temp = this.GF28X((byte)0x3, in[0][m]);
temp = temp ^ in[1][m];
temp = temp ^ in[2][m];
temp = temp ^ this.GF28X((byte)0x2, in[3][m]);
temp = temp & 0xFF;
out[3][m] = (byte) temp;
}
return out;
}
private byte[][] invVertMix (byte[][] in) {
byte[][]out = new byte[4][4];
int m;
int temp;
for (m=0; m<4; m++) {
temp = this.GF28X((byte)0x0E, in[0][m]);
temp = temp ^ this.GF28X((byte)0x0B, in[1][m]);
temp = temp ^ this.GF28X((byte)0x0D, in[2][m]);
temp = temp ^ this.GF28X((byte)0x09, in[3][m]);
temp = temp & 0xFF;
out[0][m] = (byte) temp;
}
for (m=0; m<4; m++) {
temp = this.GF28X((byte)0x09, in[0][m]);
temp = temp ^ this.GF28X((byte)0x0E, in[1][m]);
temp = temp ^ this.GF28X((byte)0x0B, in[2][m]);
temp = temp ^ this.GF28X((byte)0x0D, in[3][m]);
temp = temp & 0xFF;
out[1][m] = (byte) temp;
}
for (m=0; m<4; m++) {
temp = this.GF28X((byte)0x0D, in[0][m]);
temp = temp ^ this.GF28X((byte)0x09, in[1][m]);
temp = temp ^ this.GF28X((byte)0x0E, in[2][m]);
temp = temp ^ this.GF28X((byte)0x0B, in[3][m]);
temp = temp & 0xFF;
out[2][m] = (byte) temp;
}
for (m=0; m<4; m++) {
temp = this.GF28X((byte)0x0B, in[0][m]);
temp = temp ^ this.GF28X((byte)0x0D, in[1][m]);
temp = temp ^ this.GF28X((byte)0x09, in[2][m]);
temp = temp ^ this.GF28X((byte)0x0E, in[3][m]);
temp = temp & 0xFF;
out[3][m] = (byte) temp;
}
return out;
}
private byte[][] substitute(byte[][] in) {
byte[][] out = new byte[4][4];
int m, n;
for (m=0; m<4; m++) {
for (n=0; n<4; n++) {
out[m][n] = (byte) sbox[in[m][n] & 0xFF];
}
}
return out;
}
private byte[][] invSubstitute(byte[][] in) {
byte[][] out = new byte[4][4];
int m, n;
for (m=0; m<4; m++) {
for (n=0; n<4; n++) {
out[m][n] = (byte) invsbox[in[m][n] & 0xFF];
}
}
return out;
}
//例如keyNum = 2時,使用第2個擴展密鑰。
private byte[][] keyPlus(byte[][] in, int keyNum) {
byte[][] out = new byte[4][4];
int m, n;
for (m=0; m<4; m++) {
for (n=0; n<4; n++) {
out[n][m] = (byte) (in[n][m] ^ this.keyexpand[keyNum*4+m][n]);
}
}
return out;
}
private byte[] hex2byte(String strhex) {
if (strhex == null) {
return null;
}
int l = strhex.length();
if (l % 2 == 1) {
return null;
}
byte[] b = new byte[l / 2];
for (int i = 0; i < (l / 2); i++) {
b[i] = (byte) Integer.parseInt(strhex.substring(i * 2, i * 2 + 2), 16);
}
return b;
}
private String byte2hex(byte[] b) {
String hs = "";
String stmp = "";
for (int n = 0; n < b.length; n++) {
stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
if (stmp.length() == 1) {
hs = hs + "0" + stmp;
} else {
hs = hs + stmp;
}
}
return hs.toUpperCase();
}
private byte GF28X (byte in1, byte in2) {
int a1, a2, temp, out, n;
a1 = (int) in1 & 0xFF;
a2 = (int) in2 & 0xFF;
temp = 0;
out = 0;
for (n=0; n<8; n++) {
if ((a2 & (0x1 << n)) != 0) {
temp = temp ^ (a1 << n);
}
}
for (n=0; n<15; n++) {
if ((temp & (0x1 << n)) != 0) {
out = out ^ gf28[n];
}
}
return (byte) out;
}
//密鑰擴展
private void expandKey () {
int m, n;
byte[] temp = new byte[4];
byte temp2;
for (m=0; m<4; m++) {
for (n=0; n<4; n++) {
this.keyexpand[m][n] = this.key[m*4 + n];
}
}
for (m=4; m<44; m++) {
for (n=0; n<4; n++) {
temp[n] = this.keyexpand[m-1][n];
}
if ((m & 0x3) == 0) {
temp2 = temp[0];
for (n=0; n<3; n++) {
temp[n] = temp[n+1];
}
temp[3] = temp2;
for (n=0; n<4; n++) {
temp[n] = (byte) sbox[temp[n] & 0xFF];
}
temp[0] = (byte) (temp[0] ^ rc[m>>2]);
}
for (n=0; n<4; n++) {
this.keyexpand[m][n] = (byte) (this.keyexpand[m-4][n] ^ temp[n]);
}
}
}
public void setKey (byte[] key) {
if (key.length != 16) {
System.out.println("密鑰不是16位,密鑰設定失敗!");
return;
}
this.key = key;
this.expandKey();
return;
}
public byte[] getKey () {
return this.key;
}
public static void main(String[] args) {
AesEncrypt aes = new AesEncrypt();
byte[] key = aes.hex2byte("2B7E151628AED2A6ABF7158809CF4F3C");
byte[] mess = aes.hex2byte("3243F6A8885A308D313198A2E0370734");
byte[] enc = null;//3925841D02DC09FBDC118597196A0B32
byte[] dec = null;
aes.setKey(key);
enc = aes.encrypt(mess);
dec = aes.decrypt(enc);
System.out.println("原文:"+aes.byte2hex(mess));
System.out.println("密文:"+aes.byte2hex(enc));
System.out.println("解密:"+aes.byte2hex(dec));
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -