说明:这是一个典型的面向对象的Java程序,界面类收集用户输入的数据,数据包括64位的明文,64位的密钥;然后文本类对象Text封装用户数据,将其传递给转换类Change和核心类DES作处理,并将结果即产生的64位密文储存在该文本类对象中,然后界面将该文本的属性显示给用户.加密过程也是类似于以上这个过程.
加解密过程演示:
加密前:
加密后:
解密后:
图形用户界面类UI:
import java.applet.Applet;
import java.awt.*;
public class UI extends Applet{
Text text;
//GUI组件
private Label label1;
private Label label2;
private Label label3;
private TextField textfield1;
private TextField textfield2;
private TextField textfield3;
private Button button1;
private Button button2;
private Panel p;
private Panel p1;
private Panel p2;
//初始化变量和组件
public void init(){
label1=new Label(" 明文");
label2=new Label(" 密码");
label3=new Label(" 密文");
textfield1=new TextField("请输入明文长度为4");
textfield2=new TextField("请输入密文长度为4");
textfield3=new TextField(4);
button1=new Button("加密");
button2=new Button("解密");
p=new Panel();
p.setBackground(Color.gray);
p1=new Panel();
p2=new Panel();
p.setLayout(new BorderLayout());
p1.setLayout(new BorderLayout());
p2.setLayout(new BorderLayout());
p.add("North",label1);
p1.add("North",textfield1);
p.add(label2);
p1.add(textfield2);
p.add("South",label3);
p1.add("South",textfield3);
p2.add("West",button1);
p2.add("East",button2);
add("West",p);
add("East",p1);
add("South",p2);
setBackground(Color.gray);
}
//action 方法处理事件
public boolean action(Event e,Object o){
DES des=new DES();
//处理按纽情况
if(e.target instanceof Button){
// ****************************按纽1**************************
if(e.target==button1){
text=new Text(textfield1.getText(),textfield2.getText());
des.encrypt(text);
textfield3.setText(new String(text.getCipherText()));
//清空明文
textfield1.setText(null);
} else if(e.target==button2){
des.decrypt(text);
textfield1.setText(new String(text.getPlainText()));
textfield3.setText(null);
}
} //按纽情况结束
return true;
}
}
文本类Text:
public class Text {
private char[] plainText;
private char[] key;
private char[] cipherText;
public Text(String st1,String st2){
this.plainText=(st1+" ").substring(0, 4).toCharArray();
this.key=(st2+" ").substring(0, 4).toCharArray();
}
public char[] getCipherText() {
return cipherText;
}
public void setCipherText(String cipherText) {
this.cipherText = cipherText.toCharArray();
}
public char[] getKey() {
return key;
}
public void setKey(String key) {
this.key = key.toCharArray();
}
public char[] getPlainText() {
return plainText;
}
public void setPlainText(String plainText) {
this.plainText = plainText.toCharArray();
}
}
转换类Change:
public class Change {
//将字符转化为字节
public static byte[] charToByte(char ch){
int temp=(int)ch;
byte[] b=new byte[2];
//将高8位放在b[0],将低8位放在b[1]
for (int i=1;i>-1;i--){
b[i] = (byte)(temp&0xFF);
//向右移8位
temp >>= 8;
}
return b;
}
//将字节转化为字符
public static char byteToChar(byte[] b){
int s=0;
if(b[0]>0)
s+=b[0];
if(b[0]<0)
s+=256+b[0];
s*=256;
if(b[1]>0)
s+=b[1];
if(b[1]<0)
s+=256+b[1];
char ch=(char)s;
return ch;
}
//将字节转化为比特数组
public static byte[] bitToByteArray(byte b) {
//强制转换成int?
int temp=(int)b;
byte[] result = new byte[8];
for(int i=7;i>-1;i--){
result[i]= (byte)(temp & 0x01);
temp>>=1;
}
return result;
}
//将二维比特数组转化为字节数组
public static byte byteToBitArray(byte[] b){
byte result;
result=(byte)(b[7]|b[6]<<1|b[5]<<2|b[4]<<3|b[3]<<4|b[2]<<5|b[1]<<6|b[0]<<7);
return result;
}
}
DES类:
public class DES {
// 初始置换 IP表
private byte IP_Table[] = {
58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4,
62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8,
57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3,
61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7
};
// 最终置换 IP-1 表
private byte IPR_Table[] = {
40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31,
38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29,
36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27,
34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25
};
// S-Box之后的32位置换P表
private byte P_Table[] = {
16, 7, 20, 21, 29, 12, 28, 17,
1, 15, 23, 26, 5, 18, 31, 10,
2, 8, 24, 14, 32, 27, 3, 9,
19, 13, 30, 6, 22, 11, 4, 25
};
// 将32位扩展成48位的表
private byte E_Table[] = {
32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9,
8, 9, 10, 11, 12, 13, 12, 13, 14, 15, 16, 17,
16, 17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25,
24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32, 1
};
// 钥匙置换PC1表
private byte PC1_Table[] = {
57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18,
10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36,
63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22,
14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4
};
// 钥匙置换PC2表
private byte PC2_Table[] = {
14, 17, 11, 24, 1, 5,
3, 28, 15, 6, 21, 10,
23, 19, 12, 4, 26, 8,
16, 7, 27, 20, 13, 2,
41, 52, 31, 37, 47, 55,
30, 40, 51, 45, 33, 48,
44, 49, 39, 56, 34, 53,
46, 42, 50, 36, 29, 32
};
//DES的中的S-Boxes
private byte[][][] sbox=
{ {
{14, 4,13, 1, 2,15,11, 8, 3,10, 6,12, 5, 9, 0, 7},
{0, 15, 7, 4,14, 2,13, 1,10, 6,12,11, 9, 5, 3, 8},
{4, 1,14, 8,13, 6, 2,11,15,12, 9, 7, 3,10, 5, 0},
{15,12, 8, 2, 4, 9, 1, 7, 5,11, 3,14,10, 0, 6,13}
},
{
{15, 1, 8,14, 6,11, 3, 4, 9, 7, 2,13,12, 0, 5,10},
{3,13, 4, 7,15, 2, 8,14,12, 0, 1,10, 6, 9,11, 5},
{0,14, 7,11,10, 4,13, 1, 5, 8,12, 6, 9, 3, 2,15},
{13, 8,10, 1, 3,15, 4, 2,11, 6, 7,12, 0, 5,14, 9}
} ,
{
{10, 0, 9,14, 6, 3,15, 5, 1,13,12, 7,11, 4, 2, 8},
{13, 7, 0, 9, 3, 4, 6,10, 2, 8, 5,14,12,11,15, 1},
{13, 6, 4, 9, 8,15, 3, 0,11, 1, 2,12, 5,10,14, 7},
{1,10,13, 0, 6, 9, 8, 7, 4,15,14, 3,11, 5, 2,12}
} ,
{
{7,13,14, 3, 0, 6, 9,10, 1, 2, 8, 5,11,12, 4,15},
{13, 8,11, 5, 6,15, 0, 3, 4, 7, 2,12, 1,10,14, 9},
{10, 6, 9, 0,12,11, 7,13,15, 1, 3,14, 5, 2, 8, 4},
{3,15, 0, 6,10, 1,13, 8, 9, 4, 5,11,12, 7, 2,14}
},
{
{2,12, 4, 1, 7,10,11, 6, 8, 5, 3,15,13, 0,14, 9},
{14,11, 2,12, 4, 7,13, 1, 5, 0,15,10, 3, 9, 8, 6},
{4, 2, 1,11,10,13, 7, 8,15, 9,12, 5, 6, 3, 0,14},
{11, 8,12, 7, 1,14, 2,13, 6,15, 0, 9,10, 4, 5, 3}
},
{
{ 12, 1,10,15, 9, 2, 6, 8, 0,13, 3, 4,14, 7, 5,11},
{ 10,15, 4, 2, 7,12, 9, 5, 6, 1,13,14, 0,11, 3, 8},
{ 9,14,15, 5, 2, 8,12, 3, 7, 0, 4,10, 1,13,11, 6},
{ 4, 3, 2,12, 9, 5,15,10,11,14, 1, 7, 6, 0, 8,13}
},
{
{ 4,11, 2,14,15, 0, 8,13, 3,12, 9, 7, 5,10, 6, 1},
{ 13, 0,11, 7, 4, 9, 1,10,14, 3, 5,12, 2,15, 8, 6},
{ 1, 4,11,13,12, 3, 7,14,10,15, 6, 8, 0, 5, 9, 2},
{ 6,11,13, 8, 1, 4,10, 7, 9, 5, 0,15,14, 2, 3,12}
},
{
{ 13, 2, 8, 4, 6,15,11, 1,10, 9, 3,14, 5, 0,12, 7},
{ 1,15,13, 8,10, 3, 7, 4,12, 5, 6,11, 0,14, 9, 2},
{ 7,11, 4, 1, 9,12,14, 2, 0, 6,10,13,15, 3, 5, 8},
{ 2, 1,14, 7, 4,10, 8,13,15,12, 9, 0, 3, 5, 6,11}
}
};
byte[][] Lpart=new byte[4][8];
byte[][] Rpart=new byte[4][8];
//声明一个三维数组用来存储加密过程产生的16个密码
byte[][][] saveK=new byte[16][8][6];
public void encrypt(Text text){
byte[] byteArray=new byte[8];
byte[][]C=new byte[4][7];
byte[][]D=new byte[4][7];
byte[] byteArray2=new byte[8];
//这里byte[0]保存char[0]的高位字节,byte[1]保存了char[0]的低位字节
char [] charArray=text.getPlainText();
for(int i=0;i<8;i++){
byteArray[i]=Change.charToByte(charArray[i/2])[i%2];
}
//将byteArray中的位取出并扩展成字节放在bitArray中
byte [][] bitArray=new byte[8][8];
for(int i=0;i<8;i++){
bitArray[i]=Change.bitToByteArray(byteArray[i]);
}
//完成初始置换IP
IP(bitArray);
//将bitArray分配给2个数组Lpart和Rpart
for(int i=0;i<8;i++)
for(int j=0;j<8;j++){
if(i<4)
Lpart[i][j]=bitArray[i][j];
else
Rpart[i-4][j]=bitArray[i][j];
}
//**********对文本1中输入的处理结束************
// ***************对文本2输入的处理******************
//获得从文本2中输入的字符串,并将其存储在字符数组中
//和以上同理
char [] charArray2=text.getKey();
for(int i=0;i<8;i++){
byteArray2[i]=Change.charToByte(charArray2[i/2])[i%2];
}
byte [][] bitArray2=new byte[8][8];
for(int i=0;i<8;i++){
bitArray2[i]=Change.bitToByteArray(byteArray2[i]);
}
//bitArray2经过PC1
PC1(bitArray2);
// 将bitArray2经过PC1后的数组拆分成2组
for(int i=0;i<8;i++)
for(int j=0;j<7;j++){
if(i<4)
C[i][j]=bitArray2[i][j];
else
D[i-4][j]=bitArray2[i][j];
}
// *****************文本2的处理结束*****************
byte[][]temp;
for(int i=0;i<16;i++){
// 用临时数组temp保存明文右半部分
temp=(byte[][])Rpart.clone();
// 向左移1位的情况
if(i==0||i==1||i==8||i==15){
LS(C);
LS(D);
}
// 向左移动2位的情况
else{
LS(C);
LS(C);
LS(D);
LS(D);
}
//明文右半部分Rpart扩展成48位
Rpart=expandByte(Rpart);
//异或1
XOR(Rpart,PC2(C,D));
//在一个数组中存储K1-K16以便解密使用
saveK[i]=(PC2(C,D));
//经过SBOX
Rpart=SBOX(Rpart);
//经过置换
Perm(Rpart);
//经过异或2
XOR2(Lpart,Rpart);
//新的左边是原来的右边
Lpart=temp;
}//for结束
// 左右两部分合并然后最终置换,由于最后一次循环之后左边和右边进行了一次交换,所以这里参数的顺序是Rpart在前Lpart在后
byte[][] result=IP2(Rpart,Lpart);
// 转化为字节,然后转化为字符
char[] array=new char[4];
byte[]b=new byte[2];
for(int i=0;i<8;i++){
b[i%2]=Change.byteToBitArray(result[i]);
array[(int)(i/2)]= Change.byteToChar(b);
}
text.setCipherText(new String(array));
}
public void decrypt(Text text){
// ********************解密过程*****************
byte[][] temp2;
for(int i=15;i>-1;i--){
temp2=(byte[][])Lpart.clone();
//扩展Lpart
Lpart=expandByte(Lpart);
//经过异或1
XOR(Lpart,saveK[i]);
//经过SBOX
Lpart=SBOX(Lpart);
//经过置换Perm
Perm(Lpart);
//经过异或2和交换
XOR2(Rpart,Lpart);
Rpart=temp2;
}//for结束
//左右两部分合并然后最终置换
byte[][] result3=IP2(Lpart,Rpart);
char[] array=new char[4];
byte[]b=new byte[2];
for(int i=0;i<8;i++){
b[i%2]=Change.byteToBitArray(result3[i]);
array[(int)(i/2)]= Change.byteToChar(b);
}
}//解密结束
// ***************plaintext处理部分***************
//初始置换IP
public void IP(byte[][] in){
byte[][]out=new byte[8][8];
for(int i=0;i<64;i++)
out[i/8][i%8]=in[(IP_Table[i]-1)/8][(IP_Table[i]-1)%8];
System.arraycopy(out, 0, in, 0, 8);
}//ip结束
//扩展ExpandByte
public byte[][] expandByte(byte[][] in){
byte[][] out=new byte[8][6];
for(int i=0;i<48;i++)
out[i/6][i%6]=in[(E_Table[i]-1)/8][(E_Table[i]-1)%8];
return out;
}//扩展结束
//Rpart和K的异或
public void XOR(byte[][]c,byte[][]d){
for(int i=0;i<8;i++)
for(int j=0;j<6;j++)
c[i][j]^=d[i][j];
}
// SBOX
public byte[][] SBOX(byte[][]temp){
byte[][]xxx=new byte[4][8];
int m;
int n;
byte[][] yyy=new byte[4][2];
for (int i=0;i<8;i++){
m=temp[i][0]*2+temp[i][5];
n=temp[i][1]*8+temp[i][2]*4+temp[i][3]*2+temp[i][4];
yyy[i/2][i%2]=(byte)sbox[i][m][n];
}
for(int i=0;i<4;i++)
for(int j=1;j>-1;j--)
for(int k=0;k<4;k++){
xxx[i][3+4*j-k]=(byte)(yyy[i][j]&0x01);
yyy[i][j]>>=1;
}
return xxx;
}
// 置换perm
public void Perm(byte[][] in){
byte[][]temp=new byte[4][8];
for(int i=0;i<32;i++)
temp[i/8][i%8]=in[(P_Table[i]-1)/8][(P_Table[i]-1)%8];
System.arraycopy(temp, 0, in, 0, 4);
}
// XOR2
public void XOR2(byte[][] b, byte[][] c){
for(int i=0;i<4;i++)
for(int j=0;j<8;j++)
c[i][j]^=b[i][j];
}
// 最终置换函数
public byte[][] IP2(byte[][]b,byte[][]c){
byte[][]out=new byte[8][8];
byte[][]temp=new byte[8][8];
for(int i=0;i<32;i++){
temp[i/8][i%8]=b[i/8][i%8];
temp[i/8+4][i%8]=c[i/8][i%8];
}
for(int i=0;i<64;i++){
out[i/8][i%8] =temp[(IPR_Table[i]-1)/8][(IPR_Table[i]-1)%8];
}
return out;
}
// ***************cipherkey处理部分***************
//PC1函数
public void PC1(byte[][] in){
byte[][]temp=new byte[8][7];
for(int i=0;i<56;i++)
temp[i/7][i%7]=in[(PC1_Table[i]-1)/8][(PC1_Table[i]-1)%8];
System.arraycopy(temp, 0, in, 0, 8);
}
// LeftShift函数
public void LS(byte[][]b2){
byte temp;
temp=b2[0][0];
for(int i=0;i<4;i++)
for(int j=0;j<6;j++){
b2[i][j]=b2[i][j+1];
if(i==3)
continue;
if(j==5)
b2[i][6]=b2[i+1][0];
}
b2[3][6]=temp;
}
// PC2函数
public byte[][] PC2(byte [][]c,byte[][]d ){
byte[][]out=new byte[8][6];
byte[][]temp=new byte[8][7];
for(int i=0;i<28;i++){
temp[i/7][i%7]=c[i/7][i%7];
temp[i/7+4][i%7]=d[i/7][i%7];
}
for(int i=0;i<48;i++){
out[i/6][i%6] = temp[(PC2_Table[i]-1)/7][(PC2_Table[i]-1)%7];
}
return out;
}
}