des算法加密解密的实现(des加密解密工具代码)

2023-03-04 0:24:44 听风 思思

一.加密

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

DES算法加密过程

对DES算法加密过程图示的说明如下:待加密的64比特明文串m,经过IP置换后,得到的比特串的下标列表如下:

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

该比特串被分为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后所得比特串的下标列表如下:

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

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

下面再讲一下变换f(Ri-1,Ki)。

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

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

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 31

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

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

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

下面再讲一下S盒的变换过程。任取一S盒。见图:

在其输入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表如图所示)

至此,DES算法加密原理讲完了。在VC++6.0下的程序源代码为:

for(i=1;i=64;i++)

m1[i]=m[ip[i-1]];//64位明文串输入,经过IP置换。

下面进行迭代。由于各次迭代的方法相同只是输入输出不同,因此只给出其中一次。以第八次为例://进行第八次迭代。首先进行S盒的运算,输入32位比特串。

for(i=1;i=48;i++)//经过E变换扩充,由32位变为48位

RE1[i]=R7[E[i-1]];

for(i=1;i=48;i++)//与K8按位作不进位加法运算

RE1[i]=RE1[i]+K8[i];

for(i=1;i=48;i++)

{

if(RE1[i]==2)

RE1[i]=0;

}

for(i=1;i7;i++)//48位分成8组

{

s11[i]=RE1[i];

s21[i]=RE1[i+6];

s31[i]=RE1[i+12];

s41[i]=RE1[i+18];

s51[i]=RE1[i+24];

s61[i]=RE1[i+30];

s71[i]=RE1[i+36];

s81[i]=RE1[i+42];

}//下面经过S盒,得到8个数。S1,s2,s3,s4,s5,s6,s7,s8分别为S表

s[1]=s1[s11[6]+s11[1]*2][s11[5]+s11[4]*2+s11[3]*4+s11[2]*8];

s[2]=s2[s21[6]+s21[1]*2][s21[5]+s21[4]*2+s21[3]*4+s21[2]*8];

s[3]=s3[s31[6]+s31[1]*2][s31[5]+s31[4]*2+s31[3]*4+s31[2]*8];

s[4]=s4[s41[6]+s41[1]*2][s41[5]+s41[4]*2+s41[3]*4+s41[2]*8];

s[5]=s5[s51[6]+s51[1]*2][s51[5]+s51[4]*2+s51[3]*4+s51[2]*8];

s[6]=s6[s61[6]+s61[1]*2][s61[5]+s61[4]*2+s61[3]*4+s61[2]*8];

s[7]=s7[s71[6]+s71[1]*2][s71[5]+s71[4]*2+s71[3]*4+s71[2]*8];

s[8]=s8[s81[6]+s81[1]*2][s81[5]+s81[4]*2+s81[3]*4+s81[2]*8];

for(i=0;i8;i++)//8个数变换输出二进制

{

for(j=1;j5;j++)

{

temp[j]=s[i+1]%2;

s[i+1]=s[i+1]/2;

}

for(j=1;j5;j++)

f[4*i+j]=temp[5-j];

}

for(i=1;i33;i++)//经过P变换

frk[i]=f[P[i-1]];//S盒运算完成

for(i=1;i33;i++)//左右交换

L8[i]=R7[i];

for(i=1;i33;i++)//R8为L7与f(R,K)进行不进位二进制加法运算结果

{

R8[i]=L7[i]+frk[i];

if(R8[i]==2)

R8[i]=0;

}

[ 原创文档 本文适合中级读者 已阅读21783次 ] 文档 代码 工具

DES算法及其在VC++6.0下的实现(下)

作者:航天医学工程研究所四室 朱彦军

在《DES算法及其在VC++6.0下的实现(上)》中主要介绍了DES算法的基本原理,下面让我们继续:

二.子密钥的生成

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

子密钥生成过程具体解释如下:

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

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

该比特串分为长度相等的比特串C0和D0。然后C0和D0分别循环左移1位,得到C1和D1。C1和D1合并起来生成C1D1。C1D1经过PC-2变换后即生成48比特的K1。K1的下标列表为:

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

C1、D1分别循环左移LS2位,再合并,经过PC-2,生成子密钥K2……依次类推直至生成子密钥K16。

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

迭代顺序 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

左移位数 1 1 2 2 2 2 2 2 1 2 2 2 2 2 2 1

生成子密钥的VC程序源代码如下:

for(i=1;i57;i++)//输入64位K,经过PC-1变为56位 k0[i]=k[PC_1[i-1]];

56位的K0,均分为28位的C0,D0。C0,D0生成K1和C1,D1。以下几次迭代方法相同,仅以生成K8为例。 for(i=1;i27;i++)//循环左移两位

{

C8[i]=C7[i+2];

D8[i]=D7[i+2];

}

C8[27]=C7[1];

D8[27]=D7[1];

C8[28]=C7[2];

D8[28]=D7[2];

for(i=1;i=28;i++)

{

C[i]=C8[i];

C[i+28]=D8[i];

}

for(i=1;i=48;i++)

K8[i]=C[PC_2[i-1]];//生成子密钥k8

注意:生成的子密钥不同,所需循环左移的位数也不同。源程序中以生成子密钥 K8为例,所以循环左移了两位。但在编程中,生成不同的子密钥应以Lsi表为准。

三.解密

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

第一圈:

加密后的结果

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

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

同理类推:

得 L=R0, R=L0。

其程序源代码与加密相同。在此就不重写。

四.示例

例如:已知明文m=learning, 密钥 k=computer。

明文m的ASCII二进制表示:

m= 01101100 01100101 01100001 01110010

01101110 01101001 01101110 01100111

密钥k的ASCII二进制表示:

k=01100011 01101111 01101101 01110000

01110101 01110100 01100101 01110010

明文m经过IP置换后,得:

11111111 00001000 11010011 10100110 00000000 11111111 01110001 11011000

等分为左右两段:

L0=11111111 00001000 11010011 10100110 R0=00000000 11111111 01110001 11011000

经过16次迭代后,所得结果为:

L1=00000000 11111111 01110001 11011000 R1=00110101 00110001 00111011 10100101

L2=00110101 00110001 00111011 10100101 R2=00010111 11100010 10111010 10000111

L3=00010111 11100010 10111010 10000111 R3=00111110 10110001 00001011 10000100

L4=00111110101100010000101110000100 R4=11110111110101111111101000111110

L5=11110111110101111111101000111110 R5=10010110011001110100111111100101

L6=10010110011001110100111111100101 R6=11001011001010000101110110100111

L7=11001011001010000101110110100111 R7=01100011110011101000111011011001

L8=01100011110011101000111011011001 R8=01001011110100001111001000000100

L9=01001011110100001111001000000100 R9=00011101001101111010111011100001

L10=00011101001101111010111011100001 R10=11101110111110111111010100000101

L11=11101110111110111111010100000101 R11=01101101111011011110010111111000

L12=01101101111011011110010111111000 R12=11111101110011100111000110110111

L13=11111101110011100111000110110111 R13=11100111111001011010101000000100

L14=11100111111001011010101000000100 R14=00011110010010011011100001100001

L15=00011110010010011011100001100001 R15=01010000111001001101110110100011

L16=01010000111001001101110110100011 R16=01111101101010000100110001100001

其中,f函数的结果为:

f1=11001010001110011110100000000011 f2=00010111000111011100101101011111

f3=00001011100000000011000000100001 f4=11100000001101010100000010111001

f5=10101000110101100100010001100001 f6=00111100111111111010011110011001

f7=11110101101010011100000100111100 f8=10000000111110001010111110100011

f9=01111110111110010010000000111000 f10=10100101001010110000011100000001

f11=01110000110110100100101100011001 f12=00010011001101011000010010110010

f13=10001010000010000100111111111100 f14=11100011100001111100100111010110

f15=10110111000000010111011110100111 f16=01100011111000011111010000000000

16个子密钥为:

K1=11110000101111101110111011010000 K2=11100000101111101111011010010101

K3=11110100111111100111011000101000 K4=11100110111101110111001000011010

K5=11101110110101110111011100100110 K6=11101111110100110101101110001011

K7=00101111110100111111101111100110 K8=10111111010110011101101101010000

K9=00011111010110111101101101000100 K10=00111111011110011101110100001001

K11=00011111011011011100110101101000 K12=01011011011011011011110100001010

K13=11011101101011011010110110001111 K14=11010011101011101010111110000000

K15=11111001101111101010011011010011 K16=11110001101111100010111000000001

S盒中,16次运算时,每次的8 个结果为:

第一次:5,11,4,1,0,3,13,9;

第二次:7,13,15,8,12,12,13,1;

第三次:8,0,0,4,8,1,9,12;

第四次:0,7,4,1,7,6,12,4;

第五次:8,1,0,11,5,0,14,14;

第六次:14,12,13,2,7,15,14,10;

第七次:12,15,15,1,9,14,0,4;

第八次:15,8,8,3,2,3,14,5;

第九次:8,14,5,2,1,15,5,12;

第十次:2,8,13,1,9,2,10,2;

第十一次:10,15,8,2,1,12,12,3;

第十二次:5,4,4,0,14,10,7,4;

第十三次:2,13,10,9,2,4,3,13;

第十四次:13,7,14,9,15,0,1,3;

第十五次:3,1,15,5,11,9,11,4;

第十六次:12,3,4,6,9,3,3,0;

子密钥生成过程中,生成的数值为:

C0=0000000011111111111111111011 D0=1000001101110110000001101000

C1=0000000111111111111111110110 D1=0000011011101100000011010001

C2=0000001111111111111111101100 D2=0000110111011000000110100010

C3=0000111111111111111110110000 D3=0011011101100000011010001000

C4=0011111111111111111011000000 D4=1101110110000001101000100000

C5=1111111111111111101100000000 D5=0111011000000110100010000011

C6=1111111111111110110000000011 D6=1101100000011010001000001101

C7=1111111111111011000000001111 D7=0110000001101000100000110111

C8=1111111111101100000000111111 D8=1000000110100010000011011101

C9=1111111111011000000001111111 D9=0000001101000100000110111011

C10=1111111101100000000111111111 D10=0000110100010000011011101100

C11=1111110110000000011111111111 D11=0011010001000001101110110000

C12=1111011000000001111111111111 D12=1101000100000110111011000000

C13=1101100000000111111111111111 D13=0100010000011011101100000011

C14=0110000000011111111111111111 D14=0001000001101110110000001101

C15=1000000001111111111111111101 D15=0100000110111011000000110100

C16=0000000011111111111111111011 D16=1000001101110110000001101000

求C语言编写的DES加密解密源代码

从别的地方抄来的

#include "stdio.h"

#include "time.h"

#include "stdlib.h"

#define PLAIN_FILE_OPEN_ERROR -1

#define KEY_FILE_OPEN_ERROR -2

#define CIPHER_FILE_OPEN_ERROR -3

#define OK 1;

typedef char ElemType;

/* 初始置换表IP */

int IP_Table[64] = { 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,

56,48,40,32,24,16,8,0,

58,50,42,34,26,18,10,2,

60,52,44,36,28,20,12,4,

62,54,46,38,30,22,14,6};

/* 逆初始置换表IP^-1 */

int IP_1_Table[64] = {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,

32,0,40,8,48,16,56,24};

/* 扩充置换表E */

int E_Table[48] = {31, 0, 1, 2, 3, 4,

3, 4, 5, 6, 7, 8,

7, 8,9,10,11,12,

11,12,13,14,15,16,

15,16,17,18,19,20,

19,20,21,22,23,24,

23,24,25,26,27,28,

27,28,29,30,31, 0};

/* 置换函数P */

int P_Table[32] = {15,6,19,20,28,11,27,16,

0,14,22,25,4,17,30,9,

1,7,23,13,31,26,2,8,

18,12,29,5,21,10,3,24};

/* S盒 */

int S[8][4][16] =/* S1 */

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

/* S2 */

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

/* S3 */

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

/* S4 */

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

/* S5 */

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

/* S6 */

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

/* S7 */

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

/* S8 */

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

/* 置换选择1 */

int PC_1[56] = {56,48,40,32,24,16,8,

0,57,49,41,33,25,17,

9,1,58,50,42,34,26,

18,10,2,59,51,43,35,

62,54,46,38,30,22,14,

6,61,53,45,37,29,21,

13,5,60,52,44,36,28,

20,12,4,27,19,11,3};

/* 置换选择2 */

int PC_2[48] = {13,16,10,23,0,4,2,27,

14,5,20,9,22,18,11,3,

25,7,15,6,26,19,12,1,

40,51,30,36,46,54,29,39,

50,44,32,46,43,48,38,55,

33,52,45,41,49,35,28,31};

/* 对左移次数的规定 */

int MOVE_TIMES[16] = {1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};

int ByteToBit(ElemType ch,ElemType bit[8]);

int BitToByte(ElemType bit[8],ElemType *ch);

int Char8ToBit64(ElemType ch[8],ElemType bit[64]);

int Bit64ToChar8(ElemType bit[64],ElemType ch[8]);

int DES_MakeSubKeys(ElemType key[64],ElemType subKeys[16][48]);

int DES_PC1_Transform(ElemType key[64], ElemType tempbts[56]);

int DES_PC2_Transform(ElemType key[56], ElemType tempbts[48]);

int DES_ROL(ElemType data[56], int time);

int DES_IP_Transform(ElemType data[64]);

int DES_IP_1_Transform(ElemType data[64]);

int DES_E_Transform(ElemType data[48]);

int DES_P_Transform(ElemType data[32]);

int DES_SBOX(ElemType data[48]);

int DES_XOR(ElemType R[48], ElemType L[48],int count);

int DES_Swap(ElemType left[32],ElemType right[32]);

int DES_EncryptBlock(ElemType plainBlock[8], ElemType subKeys[16][48], ElemType cipherBlock[8]);

int DES_DecryptBlock(ElemType cipherBlock[8], ElemType subKeys[16][48], ElemType plainBlock[8]);

int DES_Encrypt(char *plainFile, char *keyStr,char *cipherFile);

int DES_Decrypt(char *cipherFile, char *keyStr,char *plainFile);

/* 字节转换成二进制 */

int ByteToBit(ElemType ch, ElemType bit[8]){

int cnt;

for(cnt = 0;cnt 8; cnt++){

*(bit+cnt) = (chcnt)1;

}

return 0;

}

/* 二进制转换成字节 */

int BitToByte(ElemType bit[8],ElemType *ch){

int cnt;

for(cnt = 0;cnt 8; cnt++){

*ch |= *(bit + cnt)cnt;

}

return 0;

}

/* 将长度为8的字符串转为二进制位串 */

int Char8ToBit64(ElemType ch[8],ElemType bit[64]){

int cnt;

for(cnt = 0; cnt 8; cnt++){

ByteToBit(*(ch+cnt),bit+(cnt3));

}

return 0;

}

/* 将二进制位串转为长度为8的字符串 */

int Bit64ToChar8(ElemType bit[64],ElemType ch[8]){

int cnt;

memset(ch,0,8);

for(cnt = 0; cnt 8; cnt++){

BitToByte(bit+(cnt3),ch+cnt);

}

return 0;

}

/* 生成子密钥 */

int DES_MakeSubKeys(ElemType key[64],ElemType subKeys[16][48]){

ElemType temp[56];

int cnt;

DES_PC1_Transform(key,temp);/* PC1置换 */

for(cnt = 0; cnt 16; cnt++){/* 16轮跌代,产生16个子密钥 */

DES_ROL(temp,MOVE_TIMES[cnt]);/* 循环左移 */

DES_PC2_Transform(temp,subKeys[cnt]);/* PC2置换,产生子密钥 */

}

return 0;

}

/* 密钥置换1 */

int DES_PC1_Transform(ElemType key[64], ElemType tempbts[56]){

int cnt;

for(cnt = 0; cnt 56; cnt++){

tempbts[cnt] = key[PC_1[cnt]];

}

return 0;

}

/* 密钥置换2 */

int DES_PC2_Transform(ElemType key[56], ElemType tempbts[48]){

int cnt;

for(cnt = 0; cnt 48; cnt++){

tempbts[cnt] = key[PC_2[cnt]];

}

return 0;

}

/* 循环左移 */

int DES_ROL(ElemType data[56], int time){

ElemType temp[56];

/* 保存将要循环移动到右边的位 */

memcpy(temp,data,time);

memcpy(temp+time,data+28,time);

/* 前28位移动 */

memcpy(data,data+time,28-time);

memcpy(data+28-time,temp,time);

/* 后28位移动 */

memcpy(data+28,data+28+time,28-time);

memcpy(data+56-time,temp+time,time);

return 0;

}

/* IP置换 */

int DES_IP_Transform(ElemType data[64]){

int cnt;

ElemType temp[64];

for(cnt = 0; cnt 64; cnt++){

temp[cnt] = data[IP_Table[cnt]];

}

memcpy(data,temp,64);

return 0;

}

/* IP逆置换 */

int DES_IP_1_Transform(ElemType data[64]){

int cnt;

ElemType temp[64];

for(cnt = 0; cnt 64; cnt++){

temp[cnt] = data[IP_1_Table[cnt]];

}

memcpy(data,temp,64);

return 0;

}

/* 扩展置换 */

int DES_E_Transform(ElemType data[48]){

int cnt;

ElemType temp[48];

for(cnt = 0; cnt 48; cnt++){

temp[cnt] = data[E_Table[cnt]];

}

memcpy(data,temp,48);

return 0;

}

/* P置换 */

int DES_P_Transform(ElemType data[32]){

int cnt;

ElemType temp[32];

for(cnt = 0; cnt 32; cnt++){

temp[cnt] = data[P_Table[cnt]];

}

memcpy(data,temp,32);

return 0;

}

/* 异或 */

int DES_XOR(ElemType R[48], ElemType L[48] ,int count){

int cnt;

for(cnt = 0; cnt count; cnt++){

R[cnt] ^= L[cnt];

}

return 0;

}

/* S盒置换 */

int DES_SBOX(ElemType data[48]){

int cnt;

int line,row,output;

int cur1,cur2;

for(cnt = 0; cnt 8; cnt++){

cur1 = cnt*6;

cur2 = cnt2;

/* 计算在S盒中的行与列 */

line = (data[cur1]1) + data[cur1+5];

row = (data[cur1+1]3) + (data[cur1+2]2)

+ (data[cur1+3]1) + data[cur1+4];

output = S[cnt][line][row];

/* 化为2进制 */

data[cur2] = (output0X08)3;

data[cur2+1] = (output0X04)2;

data[cur2+2] = (output0X02)1;

data[cur2+3] = output0x01;

}

return 0;

}

/* 交换 */

int DES_Swap(ElemType left[32], ElemType right[32]){

ElemType temp[32];

memcpy(temp,left,32);

memcpy(left,right,32);

memcpy(right,temp,32);

return 0;

}

/* 加密单个分组 */

int DES_EncryptBlock(ElemType plainBlock[8], ElemType subKeys[16][48], ElemType cipherBlock[8]){

ElemType plainBits[64];

ElemType copyRight[48];

int cnt;

Char8ToBit64(plainBlock,plainBits);

/* 初始置换(IP置换) */

DES_IP_Transform(plainBits);

/* 16轮迭代 */

for(cnt = 0; cnt 16; cnt++){

memcpy(copyRight,plainBits+32,32);

/* 将右半部分进行扩展置换,从32位扩展到48位 */

DES_E_Transform(copyRight);

/* 将右半部分与子密钥进行异或操作 */

DES_XOR(copyRight,subKeys[cnt],48);

/* 异或结果进入S盒,输出32位结果 */

DES_SBOX(copyRight);

/* P置换 */

DES_P_Transform(copyRight);

/* 将明文左半部分与右半部分进行异或 */

DES_XOR(plainBits,copyRight,32);

if(cnt != 15){

/* 最终完成左右部的交换 */

DES_Swap(plainBits,plainBits+32);

}

}

/* 逆初始置换(IP^1置换) */

DES_IP_1_Transform(plainBits);

Bit64ToChar8(plainBits,cipherBlock);

return 0;

}

/* 解密单个分组 */

int DES_DecryptBlock(ElemType cipherBlock[8], ElemType subKeys[16][48],ElemType plainBlock[8]){

ElemType cipherBits[64];

ElemType copyRight[48];

int cnt;

Char8ToBit64(cipherBlock,cipherBits);

/* 初始置换(IP置换) */

DES_IP_Transform(cipherBits);

/* 16轮迭代 */

for(cnt = 15; cnt = 0; cnt--){

memcpy(copyRight,cipherBits+32,32);

/* 将右半部分进行扩展置换,从32位扩展到48位 */

DES_E_Transform(copyRight);

/* 将右半部分与子密钥进行异或操作 */

DES_XOR(copyRight,subKeys[cnt],48);

/* 异或结果进入S盒,输出32位结果 */

DES_SBOX(copyRight);

/* P置换 */

DES_P_Transform(copyRight);

/* 将明文左半部分与右半部分进行异或 */

DES_XOR(cipherBits,copyRight,32);

if(cnt != 0){

/* 最终完成左右部的交换 */

DES_Swap(cipherBits,cipherBits+32);

}

}

/* 逆初始置换(IP^1置换) */

DES_IP_1_Transform(cipherBits);

Bit64ToChar8(cipherBits,plainBlock);

return 0;

}

/* 加密文件 */

int DES_Encrypt(char *plainFile, char *keyStr,char *cipherFile){

FILE *plain,*cipher;

int count;

ElemType plainBlock[8],cipherBlock[8],keyBlock[8];

ElemType bKey[64];

ElemType subKeys[16][48];

if((plain = fopen(plainFile,"rb")) == NULL){

return PLAIN_FILE_OPEN_ERROR;

}

if((cipher = fopen(cipherFile,"wb")) == NULL){

return CIPHER_FILE_OPEN_ERROR;

}

/* 设置密钥 */

memcpy(keyBlock,keyStr,8);

/* 将密钥转换为二进制流 */

Char8ToBit64(keyBlock,bKey);

/* 生成子密钥 */

DES_MakeSubKeys(bKey,subKeys);

while(!feof(plain)){

/* 每次读8个字节,并返回成功读取的字节数 */

if((count = fread(plainBlock,sizeof(char),8,plain)) == 8){

DES_EncryptBlock(plainBlock,subKeys,cipherBlock);

fwrite(cipherBlock,sizeof(char),8,cipher);

}

}

if(count){

/* 填充 */

memset(plainBlock + count,'\0',7 - count);

/* 最后一个字符保存包括最后一个字符在内的所填充的字符数量 */

plainBlock[7] = 8 - count;

DES_EncryptBlock(plainBlock,subKeys,cipherBlock);

fwrite(cipherBlock,sizeof(char),8,cipher);

}

fclose(plain);

fclose(cipher);

return OK;

}

/* 解密文件 */

int DES_Decrypt(char *cipherFile, char *keyStr,char *plainFile){

FILE *plain, *cipher;

int count,times = 0;

long fileLen;

ElemType plainBlock[8],cipherBlock[8],keyBlock[8];

ElemType bKey[64];

ElemType subKeys[16][48];

if((cipher = fopen(cipherFile,"rb")) == NULL){

return CIPHER_FILE_OPEN_ERROR;

}

if((plain = fopen(plainFile,"wb")) == NULL){

return PLAIN_FILE_OPEN_ERROR;

}

/* 设置密钥 */

memcpy(keyBlock,keyStr,8);

/* 将密钥转换为二进制流 */

Char8ToBit64(keyBlock,bKey);

/* 生成子密钥 */

DES_MakeSubKeys(bKey,subKeys);

/* 取文件长度 */

fseek(cipher,0,SEEK_END); /* 将文件指针置尾 */

fileLen = ftell(cipher); /* 取文件指针当前位置 */

rewind(cipher); /* 将文件指针重指向文件头 */

while(1){

/* 密文的字节数一定是8的整数倍 */

fread(cipherBlock,sizeof(char),8,cipher);

DES_DecryptBlock(cipherBlock,subKeys,plainBlock);

times += 8;

if(times fileLen){

fwrite(plainBlock,sizeof(char),8,plain);

}

else{

break;

}

}

/* 判断末尾是否被填充 */

if(plainBlock[7] 8){

for(count = 8 - plainBlock[7]; count 7; count++){

if(plainBlock[count] != '\0'){

break;

}

}

}

if(count == 7){/* 有填充 */

fwrite(plainBlock,sizeof(char),8 - plainBlock[7],plain);

}

else{/* 无填充 */

fwrite(plainBlock,sizeof(char),8,plain);

}

fclose(plain);

fclose(cipher);

return OK;

}

int main()

{ DES_Encrypt("1.txt","key.txt","2.txt");

system("pause");

DES_Decrypt("2.txt","key.txt","3.txt");

getchar();

return 0;

}

用java实现des加密和解密

一个用DES来加密、解密的类

import java.security.*;

import javax.crypto.Cipher;

import javax.crypto.SecretKey;

import javax.crypto.SecretKeyFactory;

import javax.crypto.spec.DESKeySpec;

/**

* 字符串工具集合

* @author Liudong

*/

public class StringUtils {

private static final String PASSWORD_CRYPT_KEY = "__jDlog_";

private final static String DES = "DES";

/**

* 加密

* @param src 数据源

* @param key 密钥,长度必须是8的倍数

* @return 返回加密后的数据

* @throws Exception

*/

public static byte[] encrypt(byte[] src, byte[] key)throws Exception {

//DES算法要求有一个可信任的随机数源

SecureRandom sr = new SecureRandom();

// 从原始密匙数据创建DESKeySpec对象

DESKeySpec dks = new DESKeySpec(key);

// 创建一个密匙工厂,然后用它把DESKeySpec转换成

// 一个SecretKey对象

SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);

SecretKey securekey = keyFactory.generateSecret(dks);

// Cipher对象实际完成加密操作

Cipher cipher = Cipher.getInstance(DES);

// 用密匙初始化Cipher对象

cipher.init(Cipher.ENCRYPT_MODE, securekey, sr);

// 现在,获取数据并加密

// 正式执行加密操作

return cipher.doFinal(src);

}

/**

* 解密

* @param src 数据源

* @param key 密钥,长度必须是8的倍数

* @return 返回解密后的原始数据

* @throws Exception

*/

public static byte[] decrypt(byte[] src, byte[] key)throws Exception {

// DES算法要求有一个可信任的随机数源

SecureRandom sr = new SecureRandom();

// 从原始密匙数据创建一个DESKeySpec对象

DESKeySpec dks = new DESKeySpec(key);

// 创建一个密匙工厂,然后用它把DESKeySpec对象转换成

// 一个SecretKey对象

SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);

SecretKey securekey = keyFactory.generateSecret(dks);

// Cipher对象实际完成解密操作

Cipher cipher = Cipher.getInstance(DES);

// 用密匙初始化Cipher对象

cipher.init(Cipher.DECRYPT_MODE, securekey, sr);

// 现在,获取数据并解密

// 正式执行解密操作

return cipher.doFinal(src);

}

/**

* 密码解密

* @param data

* @return

* @throws Exception

*/

public final static String decrypt(String data){

try {

return new String(decrypt(hex2byte(data.getBytes()),

PASSWORD_CRYPT_KEY.getBytes()));

}catch(Exception e) {

}

return null;

}

/**

* 密码加密

* @param password

* @return

* @throws Exception

*/

public final static String encrypt(String password){

try {

return byte2hex(encrypt(password.getBytes(),PASSWORD_CRYPT_KEY.getBytes())); }catch(Exception e) {

}

return null;

}

比较长, 转了一部分.

Des加密解密方法 用java C#和C++三种方式实现

Solaris下的系统,有一个用C做的加密工具,调用Sunwcry的des(1)对文件进行加密,然后在java中对文件进行解密。java中用的是标准的DES/CBC/NoPadding算法,可是解密后发现开头有8byte的数据出错了,请高人指点一下。

cbc_encrypt.c : 加密用的C程序

cbc_decrypt.c:解密用的C程序

TestDescbc.java:解密用的java程序

Test01.dat原始文件

Test03.dat cbc_encrypt加密后的文件

Test05.dat cbc_decrypt解密后的文件

Test06.dat TestDescbc解密后的文件

谁可以给我一个c语言写的DES代码,要求(输入任意一个字符串,可以得到相应的密文)

首先新建头文件des_encode.H

内容如下:

void EncodeMain(); //EncodeMain function

void DecodeMain(); //Sorry ,it has not used

void Decode(int *str,int *keychar); //decode :input 8 chars,8 keychars

void Encode(int *str,int *keychar); //encode: input 8 chars,8 keychars

void keyBuild(int *keychar); //create key array

void StrtoBin(int *midkey,int *keychar); //change into binary

void keyCreate(int *midkey2,int movebit,int i); //call by keyBuild

void EncodeData(int *lData,int *rData,int *srt); //encodedata function

void F(int *rData,int *key); //F function

void Expand(int *rData,int *rDataP); //Expand function

void ExchangeS(int *rDataP,int *rData); //S-diagram change

void ExchangeP(int *rData); //P change

void FillBin(int *rData,int n,int s); // data to binary;call by S-Diagram change function

void DecodeData(int *str,int *lData,int *rData); //DecodeData from binary

int IP1[]={58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, //initial change

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,

};

int IP2[]={40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31, //opp initial change

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

};

int s[][4][16]={{ //S-diagram array

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

}

};

int Ex[48]={ 32,1,2,3,4,5, //Expand array

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

};

int P[32]={16,7,20,21, //P-change

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

};

int PC1[56]={57,49,41,33,25,17,9, //PC-1 in keyBuild

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,33,15,

7,62,54,46,38,30,22,

14,6,61,53,45,37,29,

21,13,5,28,20,12,4

};

int PC2[48]={14,17,11,24,1,5, //PC-2 in keyBuild

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.cpp

内容如下:

#includestdio.h

#includestring.h

#include"des_encode.h"

int key[16][48];

char str[8];

void main() //main function

{

EncodeMain();

}

void EncodeMain() //EncodeMain function

{

int i;

char keychar[8];

int key2[8];

int strkey[8];

printf("请输入8个要加密的字符:\n");

for(i=0;i8;i++)

scanf("%c",str[i]);

getchar();

for(i=0;i8;i++)

strkey[i]=str[i];

printf("\n输入明文的十六进制为:\n");

for(i=0;i8;i++)

printf("%10x",strkey[i]);

printf("\n请输入密钥(8个字符):\n");

for(i=0;i8;i++)

scanf("%c",keychar[i]);

for(i=0;i8;i++)

key2[i]=keychar[i];

getchar();

// printf("%c",keychar[i]);

Encode(strkey,key2);

printf("\n加密后十六进制密文是:\n");

for(i=0;i8;i++)

printf("%10x",strkey[i]);

printf("\n\n清输入解密密码\n");

for(i=0;i8;i++)

scanf("%c",keychar[i]);

for(i=0;i8;i++)

key2[i]=keychar[i];

Decode(strkey,key2);

for(i=0;i8;i++)

printf("%10x",strkey[i]);

for(i=0;i8;i++)

str[i]=strkey[i];

printf("\n明文为:\t");

for(i=0;i8;i++)

printf("%c",str[i]);

printf("\n\n");

}

void keyBuild(int *keychar){ //create key array

int i,j;

int movebit[]={1,1,2,2,2,2,2,2,

1,2,2,2,2,2,2,1};

int midkey2[56];

int midkey[64];

StrtoBin(midkey,keychar);

for(i=0;i56;i++)

midkey2[i]=midkey[PC1[i]-1];

for(i=0;i16;i++)

keyCreate(midkey2,movebit[i],i);

}

void StrtoBin(int *midkey,int *keychar){ //change into binary

int trans[8],i,j,k,n;

n=0;

for(i=0;i8;i++){

j=0;

while(keychar[i]!=0){

trans[j]=keychar[i]%2;

keychar[i]=keychar[i]/2;

j++;

}

for(k=j;k8;k++)trans[k]=0;

for(k=0;k8;k++)

midkey[n++]=trans[7-k];

}

}

void keyCreate(int *midkey2,int movebit,int n){

int i,temp[4];

temp[0]=midkey2[0];

temp[1]=midkey2[1];

temp[2]=midkey2[28];

temp[3]=midkey2[29];

if(movebit==2){

for(i=0;i26;i++){

midkey2[i]=midkey2[i+2];

midkey2[i+28]=midkey2[i+30];

}

midkey2[26]=temp[0];midkey2[27]=temp[1];

midkey2[54]=temp[2];midkey2[55]=temp[3]; }

else

{ for(i=0;i27;i++){

midkey2[i]=midkey2[i+1];

midkey2[i+28]=midkey2[i+29];

}

midkey2[27]=temp[0];midkey2[55]=temp[2];

}

for(i=0;i48;i++)

key[n][i]=midkey2[PC2[i]-1];

}

void EncodeData(int *lData,int *rData,int *str){ //encodedata function

int i,j,temp[8],lint,rint;//int h;

int data[64];

lint=0,rint=0;

for(i=0;i4;i++){

j=0;

while(str[i]!=0){

temp[j]=str[i]%2;

str[i]=str[i]/2;

j++;

}

while(j8)temp[j++]=0;

for(j=0;j8;j++)

lData[lint++]=temp[7-j];

j=0;

while(str[i+4]!=0){

temp[j]=str[i+4]%2;

str[i+4]=str[i+4]/2;

j++;

}

while(j8)temp[j++]=0;

for(j=0;j8;j++)rData[rint++]=temp[7-j];

}

for(i=0;i32;i++){

data[i]=lData[i];

data[i+32]=rData[i];

}

for(i=0;i32;i++){

lData[i]=data[IP1[i]-1];//printf("P1:%5d:%5d,%5d\n",IP1[i],lData[i],data[IP1[i]-1]);

rData[i]=data[IP1[i+32]-1];

}

}

void F(int *rData,int *key){ //F function

int i,rDataP[48];

Expand(rData,rDataP);

for(i=0;i48;i++){

rDataP[i]=rDataP[i]^key[i];// printf("%10d",rDataP[i]);if((i+1)%6==0)printf("\n");

}

ExchangeS(rDataP,rData);

ExchangeP(rData);

}

void Expand(int *rData,int *rDataP){ //Expand function

int i;

for(i=0;i48;i++)

rDataP[i]=rData[Ex[i]-1];

}

void ExchangeS(int *rDataP,int *rData){ //S-diagram change

int i,n,linex,liney;

linex=liney=0;

for(i=0;i48;i+=6){

n=i/6; //printf("%10d\n",(rDataP[i]1));

linex=(rDataP[i]1)+rDataP[i+5];

liney=(rDataP[i+1]3)+(rDataP[i+2]2)+(rDataP[i+3]1)+rDataP[i+4];

FillBin(rData,n,s[n][linex][liney]);

}

}

void ExchangeP(int *rData){ //P change

int i,temp[32];

for(i=0;i32;i++)

temp[i]=rData[i];

for(i=0;i32;i++)

rData[i]=temp[P[i]-1];

}

void FillBin(int *rData,int n,int s){ // data to binary;call by S-Diagram change function

int temp[4],i;

for(i=0;i4;i++){

temp[i]=s%2;

s=s/2;

}

for(i=0;i4;i++)

rData[n*4+i]=temp[3-i];

}

void DecodeData(int *str,int *lData,int *rData){ //DecodeData from binary

int i;int a,b;int data[64];

a=0,b=0;

for(i=0;i32;i++){

data[i]=lData[i];

data[i+32]=rData[i];

}

for(i=0;i32;i++){

lData[i]=data[IP2[i]-1];

rData[i]=data[IP2[i+32]-1];

}

for(i=0;i32;i++){

a=(lData[i]0x1)+(a1);

b=(rData[i]0x1)+(b1);

if((i+1)%8==0){

str[i/8]=a;a=0;//printf("%d",i/8);

str[i/8+4]=b;b=0;//printf("%d",i/8+4);

}

}

}

void Encode(int *str,int *keychar){ //encode: input 8 chars,8 keychars

int lData[32],rData[32],temp[32],rDataP[48];

int i,j;

keyBuild(keychar);

EncodeData(lData,rData,str);

for(i=0;i16;i++){

for(j=0;j32;j++)

temp[j]=rData[j];

F(rData,key[i]);

for(j=0;j32;j++){

rData[j]=rData[j]^lData[j];

}

for(j=0;j32;j++)

lData[j]=temp[j];

}

DecodeData(str,rData,lData);

}

void Decode(int *str,int *keychar){ //decode :input 8 chars,8 keychars

int lData[32],rData[32],temp[32],rDataP[48];

int i,j;

keyBuild(keychar);

EncodeData(lData,rData,str); //这个位置

for(i=0;i16;i++){

for(j=0;j32;j++)

temp[j]=rData[j];

F(rData,key[15-i]);

for(j=0;j32;j++){

rData[j]=rData[j]^lData[j];

}

for(j=0;j32;j++){

lData[j]=temp[j];

}

}

DecodeData(str,rData,lData);

}

OK了

如果还有问题

给我发站内信

如何使用JAVA实现对字符串的DES加密和解密

java加密字符串可以使用des加密算法,实例如下:

package test;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.ObjectInputStream;

import java.io.ObjectOutputStream;

import java.security.*;

import javax.crypto.Cipher;

import javax.crypto.KeyGenerator;

import javax.crypto.SecretKey;

/**

* 加密解密

*

* @author shy.qiu

* @since

*/

public class CryptTest {

/**

* 进行MD5加密

*

* @param info

* 要加密的信息

* @return String 加密后的字符串

*/

public String encryptToMD5(String info) {

byte[] digesta = null;

try {

// 得到一个md5的消息摘要

MessageDigest alga = MessageDigest.getInstance("MD5");

// 添加要进行计算摘要的信息

alga.update(info.getBytes());

// 得到该摘要

digesta = alga.digest();

} catch (NoSuchAlgorithmException e) {

e.printStackTrace();

}

// 将摘要转为字符串

String rs = byte2hex(digesta);

return rs;

}

/**

* 进行SHA加密

*

* @param info

* 要加密的信息

* @return String 加密后的字符串

*/

public String encryptToSHA(String info) {

byte[] digesta = null;

try {

// 得到一个SHA-1的消息摘要

MessageDigest alga = MessageDigest.getInstance("SHA-1");

// 添加要进行计算摘要的信息

alga.update(info.getBytes());

// 得到该摘要

digesta = alga.digest();

} catch (NoSuchAlgorithmException e) {

e.printStackTrace();

}

// 将摘要转为字符串

String rs = byte2hex(digesta);

return rs;

}

// //////////////////////////////////////////////////////////////////////////

/**

* 创建密匙

*

* @param algorithm

* 加密算法,可用 DES,DESede,Blowfish

* @return SecretKey 秘密(对称)密钥

*/

public SecretKey createSecretKey(String algorithm) {

// 声明KeyGenerator对象

KeyGenerator keygen;

// 声明 密钥对象

SecretKey deskey = null;

try {

// 返回生成指定算法的秘密密钥的 KeyGenerator 对象

keygen = KeyGenerator.getInstance(algorithm);

// 生成一个密钥

deskey = keygen.generateKey();

} catch (NoSuchAlgorithmException e) {

e.printStackTrace();

}

// 返回密匙

return deskey;

}

/**

* 根据密匙进行DES加密

*

* @param key

* 密匙

* @param info

* 要加密的信息

* @return String 加密后的信息

*/

public String encryptToDES(SecretKey key, String info) {

// 定义 加密算法,可用 DES,DESede,Blowfish

String Algorithm = "DES";

// 加密随机数生成器 (RNG),(可以不写)

SecureRandom sr = new SecureRandom();

// 定义要生成的密文

byte[] cipherByte = null;

try {

// 得到加密/解密器

Cipher c1 = Cipher.getInstance(Algorithm);

// 用指定的密钥和模式初始化Cipher对象

// 参数:(ENCRYPT_MODE, DECRYPT_MODE, WRAP_MODE,UNWRAP_MODE)

c1.init(Cipher.ENCRYPT_MODE, key, sr);

// 对要加密的内容进行编码处理,

cipherByte = c1.doFinal(info.getBytes());

} catch (Exception e) {

e.printStackTrace();

}

// 返回密文的十六进制形式

return byte2hex(cipherByte);

}

/**

* 根据密匙进行DES解密

*

* @param key

* 密匙

* @param sInfo

* 要解密的密文

* @return String 返回解密后信息

*/

public String decryptByDES(SecretKey key, String sInfo) {

// 定义 加密算法,

String Algorithm = "DES";

// 加密随机数生成器 (RNG)

SecureRandom sr = new SecureRandom();

byte[] cipherByte = null;

try {

// 得到加密/解密器

Cipher c1 = Cipher.getInstance(Algorithm);

// 用指定的密钥和模式初始化Cipher对象

c1.init(Cipher.DECRYPT_MODE, key, sr);

// 对要解密的内容进行编码处理

cipherByte = c1.doFinal(hex2byte(sInfo));

} catch (Exception e) {

e.printStackTrace();

}

// return byte2hex(cipherByte);

return new String(cipherByte);

}

// /////////////////////////////////////////////////////////////////////////////

/**

* 创建密匙组,并将公匙,私匙放入到指定文件中

*

* 默认放入mykeys.bat文件中

*/

public void createPairKey() {

try {

// 根据特定的算法一个密钥对生成器

KeyPairGenerator keygen = KeyPairGenerator.getInstance("DSA");

// 加密随机数生成器 (RNG)

SecureRandom random = new SecureRandom();

// 重新设置此随机对象的种子

random.setSeed(1000);

// 使用给定的随机源(和默认的参数集合)初始化确定密钥大小的密钥对生成器

keygen.initialize(512, random);// keygen.initialize(512);

// 生成密钥组

KeyPair keys = keygen.generateKeyPair();

// 得到公匙

PublicKey pubkey = keys.getPublic();

// 得到私匙

PrivateKey prikey = keys.getPrivate();

// 将公匙私匙写入到文件当中

doObjToFile("mykeys.bat", new Object[] { prikey, pubkey });

} catch (NoSuchAlgorithmException e) {

e.printStackTrace();

}

}

/**

* 利用私匙对信息进行签名 把签名后的信息放入到指定的文件中

*

* @param info

* 要签名的信息

* @param signfile

* 存入的文件

*/

public void signToInfo(String info, String signfile) {

// 从文件当中读取私匙

PrivateKey myprikey = (PrivateKey) getObjFromFile("mykeys.bat", 1);

// 从文件中读取公匙

PublicKey mypubkey = (PublicKey) getObjFromFile("mykeys.bat", 2);

try {

// Signature 对象可用来生成和验证数字签名

Signature signet = Signature.getInstance("DSA");

// 初始化签署签名的私钥

signet.initSign(myprikey);

// 更新要由字节签名或验证的数据

signet.update(info.getBytes());

// 签署或验证所有更新字节的签名,返回签名

byte[] signed = signet.sign();

// 将数字签名,公匙,信息放入文件中

doObjToFile(signfile, new Object[] { signed, mypubkey, info });

} catch (Exception e) {

e.printStackTrace();

}

}

/**

* 读取数字签名文件 根据公匙,签名,信息验证信息的合法性

*

* @return true 验证成功 false 验证失败

*/

public boolean validateSign(String signfile) {

// 读取公匙

PublicKey mypubkey = (PublicKey) getObjFromFile(signfile, 2);

// 读取签名

byte[] signed = (byte[]) getObjFromFile(signfile, 1);

// 读取信息

String info = (String) getObjFromFile(signfile, 3);

try {

// 初始一个Signature对象,并用公钥和签名进行验证

Signature signetcheck = Signature.getInstance("DSA");

// 初始化验证签名的公钥

signetcheck.initVerify(mypubkey);

// 使用指定的 byte 数组更新要签名或验证的数据

signetcheck.update(info.getBytes());

System.out.println(info);

// 验证传入的签名

return signetcheck.verify(signed);

} catch (Exception e) {

e.printStackTrace();

return false;

}

}

/**

* 将二进制转化为16进制字符串

*

* @param b

* 二进制字节数组

* @return String

*/

public 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();

}

/**

* 十六进制字符串转化为2进制

*

* @param hex

* @return

*/

public byte[] hex2byte(String hex) {

byte[] ret = new byte[8];

byte[] tmp = hex.getBytes();

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

ret[i] = uniteBytes(tmp[i * 2], tmp[i * 2 + 1]);

}

return ret;

}

/**

* 将两个ASCII字符合成一个字节; 如:"EF"-- 0xEF

*

* @param src0

* byte

* @param src1

* byte

* @return byte

*/

public static byte uniteBytes(byte src0, byte src1) {

byte _b0 = Byte.decode("0x" + new String(new byte[] { src0 }))

.byteValue();

_b0 = (byte) (_b0 4);

byte _b1 = Byte.decode("0x" + new String(new byte[] { src1 }))

.byteValue();

byte ret = (byte) (_b0 ^ _b1);

return ret;

}

/**

* 将指定的对象写入指定的文件

*

* @param file

* 指定写入的文件

* @param objs

* 要写入的对象

*/

public void doObjToFile(String file, Object[] objs) {

ObjectOutputStream oos = null;

try {

FileOutputStream fos = new FileOutputStream(file);

oos = new ObjectOutputStream(fos);

for (int i = 0; i objs.length; i++) {

oos.writeObject(objs[i]);

}

} catch (Exception e) {

e.printStackTrace();

} finally {

try {

oos.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

/**

* 返回在文件中指定位置的对象

*

* @param file

* 指定的文件

* @param i

* 从1开始

* @return

*/

public Object getObjFromFile(String file, int i) {

ObjectInputStream ois = null;

Object obj = null;

try {

FileInputStream fis = new FileInputStream(file);

ois = new ObjectInputStream(fis);

for (int j = 0; j i; j++) {

obj = ois.readObject();

}

} catch (Exception e) {

e.printStackTrace();

} finally {

try {

ois.close();

} catch (IOException e) {

e.printStackTrace();

}

}

return obj;

}

/**

* 测试

*

* @param args

*/

public static void main(String[] args) {

CryptTest jiami = new CryptTest();

// 执行MD5加密"Hello world!"

System.out.println("Hello经过MD5:" + jiami.encryptToMD5("Hello"));

// 生成一个DES算法的密匙

SecretKey key = jiami.createSecretKey("DES");

// 用密匙加密信息"Hello world!"

String str1 = jiami.encryptToDES(key, "Hello");

System.out.println("使用des加密信息Hello为:" + str1);

// 使用这个密匙解密

String str2 = jiami.decryptByDES(key, str1);

System.out.println("解密后为:" + str2);

// 创建公匙和私匙

jiami.createPairKey();

// 对Hello world!使用私匙进行签名

jiami.signToInfo("Hello", "mysign.bat");

// 利用公匙对签名进行验证。

if (jiami.validateSign("mysign.bat")) {

System.out.println("Success!");

} else {

System.out.println("Fail!");

}

}

}