基于DES算法的数据文件加密解密的java编程实现

基于DES算法的数据文件加密解密的java编程实现
基于DES算法的数据文件加密解密的java编程实现

基于DES算法的数据文件加密/解密的java编程实现

1 课题背景和意义

据记载,公元前400年,古希腊人发明了置换密码。1881年世界上的第一个电话保密专利出现。在第二次世界大战期间,德国军方启用“恩尼格玛”密码机,密码学在战争中起着非常重要的作用。

随着信息化和数字化社会的发展,人们对信息安全和保密的重要性认识不断提高,于是在1997年,美国国家标准局公布实施了“美国数据加密标准(DES)”,民间力量开始全面介入密码学的研究和应用中,采用的加密算法有DES、RSA、SHA等。随着对加密强度需求的不断提高,近期又出现了AES、ECC等。我国也相应提出了自己国家的ECC、SCB2、SCH 等加密算法。

使用密码学可以达到以下目的:

1.保密性:防止用户的标识或数据被读取。

2.数据完整性:防止数据被更改。

3.身份验证:确保数据发自特定的一方。

随着计算机和通信网络的广泛应用,信息的安全性已经受到人们的普遍重视。信息安全已不仅仅局限于政治,军事以及外交领域,而且现在也与人们的日常生活息息相关。现在,密码学理论和技术已得到了迅速的发展,它是信息科学和技术中的一个重要研究领域。在近代密码学上值得一提的大事有两件:一是1977年美国国家标准局正式公布实施了美国的数据加密标准(DES),公开它的加密算法,并批准用于非机密单位及商业上的保密通信。密码学的神秘面纱从此被揭开。二是Diffie和Hellman联合写的一篇文章“密码学的新方向”,提出了适应网络上保密通信的公钥密码思想,拉开了公钥密码研究的序幕。

DES(Data Encryption Standard)是IBM公司于上世纪1977年提出的一种数据加密算法。在过去近三十年的应用中,还无法将这种加密算法完全、彻底地破解掉。而且这种算法的加解密过程非常快,至今仍被广泛应用,被公认为安全的。虽然近年来由于硬件技术的飞速发展,破解DES已经不是一件难事,但学者们似乎不甘心让这样一个优秀的加密算法从此废弃不用,于是在DES的基础上有开发了双重DES(DoubleDES,DDES)和三重DES(Triple DES,TDES)。

在国内,随着三金工程尤其是金卡工程的启动,DES算法在POS、ATM、磁卡及智能卡(IC 卡)、加油站、高速公路收费站等领域被广泛应用,以此来实现关键数据的保密,如信用卡持卡人的PIN码加密传输,IC卡与POS间的双向认证、金融交易数据包的MAC 校验等,均用到DES算法。DES加密体制是ISO颁布的数据加密标准。

因此研究DES还是有非常重要的意义。

1.1 课题目标和意义

题目:利用DES的加密算法实现针对二进制数据(文件)的加/解密软件工具。采用java语言,软件版本:jdk1.6.0, JCreator Pro v3.5.013汉化版,平台:Windows XP

意义:了解DES加密算法及原理,掌握其基本应用,利用java编程实现。

2 DES算法原理

DES算法由加密、子密钥和解密的生成三部分组成。现将DES算法介绍如下。

1.加密

DES算法处理的数据对象是一组64比特的明文串。设该明文串为m=m1m2…m64 (mi=0或1)。明文串经过64比特的密钥K来加密,最后生成长度为64比特的密文E。其加密过程图示如下:

图2-1:DES算法加密过程

对DES算法加密过程图示的说明如下:

待加密的64比特明文串m,经过IP置换(初始置换)后,得到的比特串的下标列表如下:

表2-1:得到的比特串的下标列表

该比特串被分为32位的L0和32位的R0两部分。R0子密钥K1(子密钥的生成将在后面讲)经过变换f(R0,K1)(f变换将在下面讲)输出32位的比特串f1,f1与L0做不进位的二进制加法运算。运算规则为:

f1与L0做不进位的二进制加法运算后的结果赋给R1,R0则原封不动的赋给L1。L1与R0又做与以上完全相同的运算,生成L2,R2……一共经过16次运算。最后生成R16和L16。其中R16为L15与f(R15,K16)做不进位二进制加法运算的结果,L16是R15的直接赋值。

R16与L16合并成64位的比特串。值得注意的是R16一定要排在L16前面。R16与L16合并后成的比特串,经过置换IP-1(终结置换)后所得比特串的下标列表如下:

表2-2:置换后所得比特串的下标列表

经过置换IP-1后生成的比特串就是密文e。

变换f(Ri-1,Ki):

它的功能是将32比特的输入再转化为32比特的输出。其过程如图2-2所示:

图2-2:将32比特的输入再转化为32比特的输出

f变换说明:输入Ri-1(32比特)经过变换E(扩展置换E)后,膨胀为48比特。膨胀后的比特串的下标列表如下:

表2-3:膨胀后的比特串的下标列表

膨胀后的比特串分为8组,每组6比特。各组经过各自的S盒后,又变为4比特(具体过程见后),合并后又成为32比特。该32比特经过P变换(压缩置换P)后,其下标列表如下:

表2-4:压缩置换P后的下标列表

经过P变换后输出的比特串才是32比特的f(Ri-1,Ki).

S盒的变换过程: 任取一S盒。见图2-3:

图2-3

在其输入b1,b2,b3,b4,b5,b6中,计算出x=b1*2+b6, y=b5+b4*2+b3*4+b2*8,再从Si表中查出x行,y列的值Sxy。将Sxy化为二进制,即得Si盒的输出。(S表如图2-4所示)

图2-4

以上是DES算法加密原理

加密过程实现(JAV A主要源代码)

输入64位明文串,经过IP置换:

for (i = 0; i < 64; i++) {

M[i] = timeData[IP[i] - 1];

}

迭代(由于各次迭代的方法相同只是输入输出不同,因此以任意一次为例):首先进行S盒的运算。

输入32位比特串, 经过E变换,由32位变为48位:

for (i = 0; i < 48; i++) {

RE[i] = R0[E[i] - 1];

与keyarray[times][i]按位作不进位加法运:

RE[i] = RE[i] + keyarray[times][i];

if (RE[i] == 2) {

RE[i] = 0;

}

48位分成8组:

for(i=0;i<8;i++){

for(j=0;j<6;j++){

S[i][j]=RE[(i*6)+j];}

}

经过S盒,得到8个数:

sBoxData[i] = S_Box[i][(S[i][0] << 1) + S[i][5]][(S[i][1] << 3)

+ (S[i][2] << 2) + (S[i][3] << 1) + S[i][4]];

将8个数变换输出二进制:

for (j = 0; j < 4; j++) {

sValue[((i * 4) + 3) - j] = sBoxData[i] % 2;

sBoxData[i] = sBoxData[i] / 2;

}

经过P变换:

RP[i] = sValue[P[i] - 1];

至此,S盒运算完成

左右交换:

L1[i] = R0[i];

R1[i] = L0[i] + RP[i];

Ri为Li-1与f(R,K)进行不进位二进制加法运算结果:

R1[i] = L0[i] + RP[i];

if (R1[i] == 2) {

R1[i] = 0;

}

各次迭代类似,可以依此类推。

2.子密钥的生成

64比特的密钥生成16个48比特的子密钥。其生成过程见图2-5:

图2-5子密钥生成过程

具体解释如下:

64比特的密钥K,经过PC-1(置换A)后,生成56比特的串。其下标如表所示:

表2-5:生成56比特的串

C1和D1。C1和D1合并起来生成C1D1。C1D1经过PC-2(置换B)变换后即生成48比特的K1。K1的下标列表为:

表2-6:K1的下标列表

C1、D1

子密钥K16。注意:Lsi (I =1,2,….16)的数值是不同的。具体见下表:

表2-7:生成子密钥

子密钥的生成(JA V A源代码):

输入64位K,经过PC-1变为56位:

for (i = 0; i < 56; i++) {

K0[i] = key[PC_1[i] - 1];

}

56位的K0,均分为28位的C0,D0。C0,D0生成K1和C1,D1(以下几次迭代方法相同,仅以生成任意一次为例):

if (offset == 1) {

for (i = 0; i < 27; i++) { // 循环左移一位

c1[i] = c0[i + 1];

d1[i] = d0[i + 1];

}

c1[27] = c0[0];

d1[27] = d0[0];

} else if (offset == 2) {

for (i = 0; i < 26; i++) { // 循环左移两位

c1[i] = c0[i + 2];

d1[i] = d0[i + 2];

}

c1[26] = c0[0];

d1[26] = d0[0];

c1[27] = c0[1];

d1[27] = d0[1];

}

for (i = 0; i < 28; i++) {

k[i] = c1[i]; //生成子密钥ki

k[i + 28] = d1[i];

}

注意:生成的子密钥不同,所需循环左移的位数也不同。在编程中,生成不同的子密钥应以上述offset表为准。

3.解密

DES的解密过程和DES的加密过程完全类似,只不过将16圈的子密钥序列K1,K2……K16的顺序倒过来。即第一圈用第16个子密钥K16,第二圈用K15,其余类推。

第一圈:

图2-6

加密后的结果

图2-7:加密后的结果

L=R15, R=L15⊕f(R15,K16)⊕f(R15,K16)=L15

同理R15=L14⊕f(R14,K15), L15=R14。

同理类推:

得L=R0, R=L0。

其程序源代码与加密相同。

3程序设计步骤

3.1 程序设计步骤

3.1.1程序开发平台及工具

软件版本:jdk1.6.0, JCreator Pro v3.5.013汉化版

平台:Windows XP

3.1.2源代码:

public class DesUtil {

byte[] bytekey;

public DesUtil(String strKey) {

this.bytekey = strKey.getBytes();

}// 声明常量字节数组

private static final int[] IP = { 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 }; // 64

private static final int[] IP_1 = { 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 }; // 64

private static final int[] PC_1 = { 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 }; // 56

private static final int[] PC_2 = { 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 }; // 48

private static final int[] E = { 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 }; // 48 private static final int[] P = { 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

private static final int[][][] S_Box = {//S-盒

{// S_Box[1]

{ 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 } },

{ // S_Box[2]

{ 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 } },

{ // S_Box[3]

{ 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 } },

{ // S_Box[4]

{ 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 } },

{ // S_Box[5]

{ 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 } },

{ // S_Box[6]

{ 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 } },

{ // S_Box[7]

{ 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 } },

{ // S_Box[8]

{ 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 } }

};

private static final int[] LeftMove = { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2,2, 2, 2, 1 };

// 左移位置列表

private byte[] UnitDes(byte[] des_key, byte[] des_data, int flag) {

// 检测输入参数格式是否正确,错误直接返回空值(null)

if ((des_key.length != 8) || (des_data.length != 8)|| ((flag != 1) && (flag != 0))) {

throw new RuntimeException("Data Format Error !");

}

int flags = flag;// 二进制加密密钥

int[] keydata = new int[64];// 二进制加密数据

int[] encryptdata = new int[64]; // 加密操作完成后的字节数组

byte[] EncryptCode = new byte[8];// 密钥初试化成二维数组

int[][] KeyArray = new int[16][48];// 将密钥字节数组转换成二进制字节数组

keydata = ReadDataToBirnaryIntArray(des_key);// 将加密数据字节数组转换成二进制字节数组

encryptdata = ReadDataToBirnaryIntArray(des_data);// 初试化密钥为二维密钥数组KeyInitialize(keydata, KeyArray); // 执行加密解密操作

EncryptCode = Encrypt(encryptdata, flags, KeyArray);

return EncryptCode;

}// 初试化密钥数组

private void KeyInitialize(int[] key, int[][] keyarray) {

int i;

int j;

int[] K0 = new int[56];// 特别注意:xxx[IP[i]-1]等类似变换

for (i = 0; i < 56; i++) {

K0[i] = key[PC_1[i] - 1]; // 密钥进行PC-1变换

}

for (i = 0; i < 16; i++) {

LeftBitMove(K0, LeftMove[i]); // 特别注意:xxx[IP[i]-1]等类似变换

for (j = 0; j < 48; j++) {

keyarray[i][j] = K0[PC_2[j] - 1]; // 生成子密钥keyarray[i][j]

}

}

} // 执行加密解密操作

private byte[] Encrypt(int[] timeData, int flag, int[][] keyarray) {

int i;

byte[] encrypt = new byte[8];

int flags = flag;

int[] M = new int[64];

int[] MIP_1 = new int[64];

// 特别注意:xxx[IP[i]-1]等类似变换

for (i = 0; i < 64; i++) {

M[i] = timeData[IP[i] - 1]; // 明文IP变换

}

if (flags == 1) { // 加密

for (i = 0; i < 16; i++) {

LoopF(M, i, flags, keyarray);

}

} else if (flags == 0) { // 解密

for (i = 15; i > -1; i--) {

LoopF(M, i, flags, keyarray);

}

}

for (i = 0; i < 64; i++) {

MIP_1[i] = M[IP_1[i] - 1]; // 进行IP-1运算

}

GetEncryptResultOfByteArray(MIP_1, encrypt);// 返回加密数据return encrypt;

}

private int[] ReadDataToBirnaryIntArray(byte[] intdata) {

int i;

int j;

// 将数据转换为二进制数,存储到数组

int[] IntDa = new int[8];

for (i = 0; i < 8; i++) {

IntDa[i] = intdata[i];

if (IntDa[i] < 0) {

IntDa[i] += 256;

IntDa[i] %= 256;

}

}

int[] IntVa = new int[64];

for (i = 0; i < 8; i++) {

for (j = 0; j < 8; j++) {

IntVa[((i * 8) + 7) - j] = IntDa[i] % 2;

IntDa[i] = IntDa[i] / 2;

}

}

return IntVa;

}

private void LeftBitMove(int[] k, int offset) {

int i;

// 循环移位操作函数

int[] c0 = new int[28];

int[] d0 = new int[28];

int[] c1 = new int[28];

int[] d1 = new int[28];

for (i = 0; i < 28; i++) {

c0[i] = k[i];

d0[i] = k[i + 28];

}

if (offset == 1) {

for (i = 0; i < 27; i++) { // 循环左移一位

c1[i] = c0[i + 1];

d1[i] = d0[i + 1];

}

c1[27] = c0[0];

d1[27] = d0[0];

} else if (offset == 2) {

for (i = 0; i < 26; i++) { // 循环左移两位

c1[i] = c0[i + 2];

d1[i] = d0[i + 2];

}

c1[26] = c0[0];

d1[26] = d0[0];

c1[27] = c0[1];

d1[27] = d0[1];

}

for (i = 0; i < 28; i++) {

k[i] = c1[i];

k[i + 28] = d1[i];

}

}

private void LoopF(int[] M, int times, int flag, int[][] keyarray) {

int i;

int j;

int[] L0 = new int[32];

int[] R0 = new int[32];

int[] L1 = new int[32];

int[] R1 = new int[32];

int[] RE = new int[48];

int[][] S = new int[8][6];

int[] sBoxData = new int[8];

int[] sValue = new int[32];

int[] RP = new int[32];

for (i = 0; i < 32; i++) {

L0[i] = M[i]; // 明文左侧的初始化

R0[i] = M[i + 32]; // 明文右侧的初始化

}

for (i = 0; i < 48; i++) {

RE[i] = R0[E[i] - 1]; // 经过E变换扩充,由32位变为48位

RE[i] = RE[i] + keyarray[times][i]; // 与KeyArray[times][i]按位作不进位加法运算if (RE[i] == 2) {

RE[i] = 0;

}

}

for (i = 0; i < 8; i++) { // 48位分成8组

for (j = 0; j < 6; j++) {

S[i][j] = RE[(i * 6) + j];

}

// 下面经过S盒,得到8个数

sBoxData[i] = S_Box[i][(S[i][0] << 1) + S[i][5]][(S[i][1] << 3)

+ (S[i][2] << 2) + (S[i][3] << 1) + S[i][4]];

// 8个数变换输出二进制

for (j = 0; j < 4; j++) {

sValue[((i * 4) + 3) - j] = sBoxData[i] % 2;

sBoxData[i] = sBoxData[i] / 2;

}

}

for (i = 0; i < 32; i++) {

RP[i] = sV alue[P[i] - 1]; // 经过P变换

L1[i] = R0[i]; // 右边移到左边

R1[i] = L0[i] + RP[i];

if (R1[i] == 2) {

R1[i] = 0;

}

// 重新合成M,返回数组M

// 最后一次变换时,左右不进行互换。此处采用两次变换实现不变if (((flag == 0) && (times == 0)) || ((flag == 1) && (times == 15))) {

M[i] = R1[i];

M[i + 32] = L1[i];

}

else {

M[i] = L1[i];

M[i + 32] = R1[i];

}

}

}

private void GetEncryptResultOfByteArray(int[] data, byte[] value) {

int i;

int j; // 将存储64位二进制数据的数组中的数据转换为八个整数(byte)for (i = 0; i < 8; i++) {

for (j = 0; j < 8; j++) {

value[i] += (data[(i << 3) + j] << (7 - j));

}

}

for (i = 0; i < 8; i++) {

value[i] %= 256;

if (value[i] > 128) {

value[i] -= 255;

}

}

}

private byte[] ByteDataFormat(byte[] data, int flag) {

int len = data.length;

int padlen = 8 - (len % 8);

int newlen = len + padlen;

byte[] newdata = new byte[newlen];

System.arraycopy(data, 0, newdata, 0, len);

for (int i = len; i < newlen; i++)

newdata[i] = (byte) padlen;

return newdata;

}

public byte[] DesEncrypt(byte[] des_data, int flag) {

byte[] format_key = ByteDataFormat(bytekey, flag);

byte[] format_data = ByteDataFormat(des_data, flag);

int datalen = format_data.length;

int unitcount = datalen / 8;

byte[] result_data = new byte[datalen];

for (int i = 0; i < unitcount; i++) {

byte[] tmpkey = new byte[8];

byte[] tmpdata = new byte[8];

System.arraycopy(format_key, 0, tmpkey, 0, 8);

System.arraycopy(format_data, i * 8, tmpdata, 0, 8);

byte[] tmpresult = UnitDes(tmpkey, tmpdata, flag);

System.arraycopy(tmpresult, 0, result_data, i * 8, 8);

} // 当前为解密过程,去掉加密时产生的填充位

byte[] decryptbytearray = null;

if (flag == 0) {

int total_len = datalen;

int delete_len = result_data[total_len - 8 - 1];

delete_len = ((delete_len >= 1) && (delete_len <= 8)) ? delete_len : 0;

decryptbytearray = new byte[total_len - delete_len - 8];

boolean del_flag = true;

for (int k = 0; k < delete_len; k++) {

if (delete_len != result_data[total_len - 8 - (k + 1)])

del_flag = false;

}

if (del_flag == true) {

System.arraycopy(result_data, 0, decryptbytearray, 0, total_len- delete_len - 8);

}

}

return (flag == 1) ? result_data : decryptbytearray;

}

public static void main(String[] args) {

String key = "这是密钥";

String data = "这是明文";

DesUtil desUtil = new DesUtil(key);

System.err.println("加密前明文:" + data);

// 加密后的byte型的密文

byte[] result = desUtil.DesEncrypt(data.getBytes(), 1);

System.err.println("加密后密文:" + new String(result));

// 下句直接把byte类型的密文解密

System.err.println("解密后明文:"+ new String(desUtil.DesEncrypt(result, 0))); }

}

4 系统的测试与评价

运行结果:

图4-1:运行结果

5 小结

本文的论述是基于DES算法分析的实现,DES的工作模式,DES的安全性及其应用,重点对DES对DES算法的流程做一个详细的描述,对算法的数学基础和函数描述也有比较详细的描述,应用JA V A语言实现DES的最基本的核心算法,从而对DES有更深的理解。

通过此次课程设计,不仅使自己对信息安全有了初步了解,同时使自己编程能力有了较大的提高。基本掌握了JA V A结构化程序设计。并且熟悉掌握了密码学中一个重要的算法—DES密码算法,并且通过JA V A工具编程实现。

但是由于对JA V A的图形用户界面的设计理解不深,编写的窗口无法对时间进行处理,最终只有放弃编写窗口。

参考文献

(1)专著中的文献

[1] Douglas R.Stinson著冯登国译Cryptography Theory and Practice (Second Edition)电子工业出版社2006.

[2] William Stallings著孟庆树王丽娜傅建明等译Cryptography and Network Security Principles and Practices,Fourth Edition电子工业出版社2007.

[3]郝玉洁刘贵松秦科晏华编著信息安全概论电子科技大学出版社2007.

[4]耿祥义张跃平编著Java2实用教程清华大学出版社2008.

[5]雍俊海编著Java程序设计教程(第2版)清华大学出版社2007.

相关主题
相关文档
最新文档