des算法实现
‘壹’ 求教des算法的详细过程
des算法的详细过程:
1-1、变换密钥
取得64位的密钥,每个第8位作为奇偶校验位。
1-2、变换密钥。
1-2-1、舍弃64位密钥中的奇偶校验位,根据下表(PC-1)进行密钥变换得到56位的密钥,在变换中,奇偶校验位以被舍弃。
Permuted Choice 1 (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
1-2-2、将变换后的密钥分为两个部分,开始的28位称为C[0],最后的28位称为D[0]。
1-2-3、生成16个子密钥,初始I=1。
1-2-3-1、同时将C[I]、D[I]左移1位或2位,根据I值决定左移的位数。见下表
I: 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
1-2-3-2、将C[I]D[I]作为一个整体按下表(PC-2)变换,得到48位的K[I]
Permuted Choice 2 (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
1-2-3-3、从1-2-3-1处循环执行,直到K[16]被计算完成。
2、处理64位的数据
2-1、取得64位的数据,如果数据长度不足64位,应该将其扩展为64位(例如补零)
2-2、将64位数据按下表变换(IP)
Initial Permutation (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
2-3、将变换后的数据分为两部分,开始的32位称为L[0],最后的32位称为R[0]。
2-4、用16个子密钥加密数据,初始I=1。
2-4-1、将32位的R[I-1]按下表(E)扩展为48位的E[I-1]
Expansion (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
2-4-2、异或E[I-1]和K[I],即E[I-1] XOR K[I]
2-4-3、将异或后的结果分为8个6位长的部分,第1位到第6位称为B[1],第7位到第12位称为B[2],依此类推,第43位到第48位称为B[8]。
2-4-4、按S表变换所有的B[J],初始J=1。所有在S表的值都被当作4位长度处理。
2-4-4-1、将B[J]的第1位和第6位组合为一个2位长度的变量M,M作为在S[J]中的行号。
2-4-4-2、将B[J]的第2位到第5位组合,作为一个4位长度的变量N,N作为在S[J]中的列号。
2-4-4-3、用S[J][M][N]来取代B[J]。
Substitution Box 1 (S[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[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[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[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[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[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[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[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
2-4-4-4、从2-4-4-1处循环执行,直到B[8]被替代完成。
2-4-4-5、将B[1]到B[8]组合,按下表(P)变换,得到P。
Permutation 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
2-4-6、异或P和L[I-1]结果放在R[I],即R[I]=P XOR L[I-1]。
2-4-7、L[I]=R[I-1]
2-4-8、从2-4-1处开始循环执行,直到K[16]被变换完成。
2-4-5、组合变换后的R[16]L[16](注意:R作为开始的32位),按下表(IP-1)变换得到最后的结果。
Final Permutation (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
以上就是DES算法的描述。
‘贰’ 如何实现DES算法
1.1 密钥生成
1.1.1 取得密钥
1.1.2 等分密钥
1.1.3 密钥移位
1.1.4 密钥的选取
1. 2 数据的加密操作
1.2.1 取得数据
1.2.2 初始换位
1.2.3 数据扩展
1.2.4 数据压缩
1.2.5 数据换位
1.2.6 交换数据
1.2.7 迭代
1.2.8 数据整理
详见参考资料,里面附带了源码实现。
‘叁’ 基于c语言的DES加密算法的实现 要怎么写啊
首先c语言要熟悉,然后去图书馆借一本加密解密的书,要里面有c语言des实现代码的(这种书是有的,我看到过)。论文先对加密解密的历史及发展现状进行介绍,然后着重对des加密的发展历史及原理进行阐述(以上内容要多借几本相关书综合一下用自己的语言表达出来)。然后对des的算法写个程序(可以利用书里面的程序),然后运行结果截几张图下来。最后总结一下,论文就可以了。
‘肆’ 用C语言实现DES算法
LZ。。。幻想啥呢。一般大家就算做过,也不会在这里因为80分就把算法给你。
再说了,没做过的,更不可能因为80分给你做一个。。。
还是去图书馆吧...这个。。。
‘伍’ des算法加密解密的实现
本文介绍了一种国际上通用的加密算法—DES算法的原理,并给出了在VC++6.0语言环境下实现的源代码。最后给出一个示例,以供参考。
关键字:DES算法、明文、密文、密钥、VC;
本文程序运行效果图如下:
正文:
当今社会是信息化的社会。为了适应社会对计算机数据安全保密越来越高的要求,美国国家标准局(NBS)于1997年公布了一个由IBM公司研制的一种加密算法,并且确定为非机要部门使用的数据加密标准,简称DES(Data Encrypton Standard)。自公布之日起,DES算法作为国际上商用保密通信和计算机通信的最常用算法,一直活跃在国际保密通信的舞台上,扮演了十分突出的角色。现将DES算法简单介绍一下,并给出实现DES算法的VC源代码。
DES算法由加密、解密和子密钥的生成三部分组成。
一.加密
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;i<7;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;i<8;i++)//8个数变换输出二进制
{
for(j=1;j<5;j++)
{
temp[j]=s[i+1]%2;
s[i+1]=s[i+1]/2;
}
for(j=1;j<5;j++)
f[4*i+j]=temp[5-j];
}
for(i=1;i<33;i++)//经过P变换
frk[i]=f[P[i-1]];//S盒运算完成
for(i=1;i<33;i++)//左右交换
L8[i]=R7[i];
for(i=1;i<33;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;i<57;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;i<27;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= R4=
L5= R5=
L6= R6=
L7= R7=
L8= R8=
L9= R9=
L10= R10=
L11= R11=
L12= R12=
L13= R13=
L14= R14=
L15= R15=
L16= R16=
其中,f函数的结果为:
f1= f2=
f3= f4=
f5= f6=
f7= f8=
f9= f10=
f11= f12=
f13= f14=
f15= f16=
16个子密钥为:
K1= K2=
K3= K4=
K5= K6=
K7= K8=
K9= K10=
K11= K12=
K13= K14=
K15= K16=
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
解密过程与加密过程相反,所得的数据的顺序恰好相反。在此就不赘述。
参考书目:
《计算机系统安全》 重庆出版社 卢开澄等编着
《计算机密码应用基础》 科学出版社 朱文余等编着
《Visual C++ 6.0 编程实例与技巧》 机械工业出版社 王华等编着
‘陆’ des算法是什么
DES算法为密码体制中的对称密码体制,又被称为美国数据加密标准,是1972年美国IBM公司研制的对称密码体制加密算法。
相关如下
明文按64位进行分组,密钥长64位,密钥事实上是56位参与DES运算(第8、16、24、32、40、48、56、64位是校验位, 使得每个密钥都有奇数个1)分组后的明文组和56位的密钥按位替代或交换的方法形成密文组的加密方法。
‘柒’ des加密算法(c/c++)
des.h文件:
#ifndefCRYPTOPP_DES_H
#defineCRYPTOPP_DES_H
#include"cryptlib.h"
#include"misc.h"
NAMESPACE_BEGIN(CryptoPP)
classDES:publicBlockTransformation
{
public:
DES(constbyte*userKey,CipherDir);
voidProcessBlock(constbyte*inBlock,byte*outBlock)const;
voidProcessBlock(byte*inoutBlock)const
{DES::ProcessBlock(inoutBlock,inoutBlock);}
enum{KEYLENGTH=8,BLOCKSIZE=8};
unsignedintBlockSize()const{returnBLOCKSIZE;}
protected:
staticconstword32Spbox[8][64];
SecBlock<word32>k;
};
classDESEncryption:publicDES
{
public:
DESEncryption(constbyte*userKey)
:DES(userKey,ENCRYPTION){}
};
classDESDecryption:publicDES
{
public:
DESDecryption(constbyte*userKey)
:DES(userKey,DECRYPTION){}
};
classDES_EDE_Encryption:publicBlockTransformation
{
public:
DES_EDE_Encryption(constbyte*userKey)
:e(userKey,ENCRYPTION),d(userKey+DES::KEYLENGTH,DECRYPTION){}
voidProcessBlock(constbyte*inBlock,byte*outBlock)const;
voidProcessBlock(byte*inoutBlock)const;
enum{KEYLENGTH=16,BLOCKSIZE=8};
unsignedintBlockSize()const{returnBLOCKSIZE;}
private:
DESe,d;
};
classDES_EDE_Decryption:publicBlockTransformation
{
public:
DES_EDE_Decryption(constbyte*userKey)
:d(userKey,DECRYPTION),e(userKey+DES::KEYLENGTH,ENCRYPTION){}
voidProcessBlock(constbyte*inBlock,byte*outBlock)const;
voidProcessBlock(byte*inoutBlock)const;
enum{KEYLENGTH=16,BLOCKSIZE=8};
unsignedintBlockSize()const{returnBLOCKSIZE;}
private:
DESd,e;
};
classTripleDES_Encryption:publicBlockTransformation
{
public:
TripleDES_Encryption(constbyte*userKey)
:e1(userKey,ENCRYPTION),d(userKey+DES::KEYLENGTH,DECRYPTION),
e2(userKey+2*DES::KEYLENGTH,ENCRYPTION){}
voidProcessBlock(constbyte*inBlock,byte*outBlock)const;
voidProcessBlock(byte*inoutBlock)const;
enum{KEYLENGTH=24,BLOCKSIZE=8};
unsignedintBlockSize()const{returnBLOCKSIZE;}
private:
DESe1,d,e2;
};
classTripleDES_Decryption:publicBlockTransformation
{
public:
TripleDES_Decryption(constbyte*userKey)
:d1(userKey+2*DES::KEYLENGTH,DECRYPTION),e(userKey+DES::KEYLENGTH,ENCRYPTION),
d2(userKey,DECRYPTION){}
voidProcessBlock(constbyte*inBlock,byte*outBlock)const;
voidProcessBlock(byte*inoutBlock)const;
enum{KEYLENGTH=24,BLOCKSIZE=8};
unsignedintBlockSize()const{returnBLOCKSIZE;}
private:
DESd1,e,d2;
};
NAMESPACE_END
#endif
des.cpp文件:
//des.cpp-modifiedbyWeiDaifrom:
/*
*
*circa1987,'s1977
*publicdomaincode.,but
*theactualencrypt/
*Outerbridge'sDEScodeasprintedinSchneier's"AppliedCryptography."
*
*Thiscodeisinthepublicdomain.Iwouldappreciatebugreportsand
*enhancements.
*
*PhilKarnKA9Q,[email protected],August1994.
*/
#include"pch.h"
#include"misc.h"
#include"des.h"
NAMESPACE_BEGIN(CryptoPP)
/*
*Threeofthesetables,theinitialpermutation,thefinal
*,areregularenoughthat
*forspeed,wehard-codethem.They'rehereforreferenceonly.
*Also,,gensp.c,
*tobuildthecombinedSPbox,Spbox[].They'realsoherejust
*forreference.
*/
#ifdefnotdef
/*initialpermutationIP*/
staticbyteip[]={
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
};
/*finalpermutationIP^-1*/
staticbytefp[]={
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
};
/*expansionoperationmatrix*/
staticbyteei[]={
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
};
/*The(in)famousS-boxes*/
staticbytesbox[8][64]={
/*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
};
/*32--boxes*/
staticbytep32i[]={
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
};
#endif
/*permutedchoicetable(key)*/
staticconstbytepc1[]={
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
};
/*numberleftrotationsofpc1*/
staticconstbytetotrot[]={
1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28
};
/*permutedchoicekey(table)*/
staticconstbytepc2[]={
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
};
/*EndofDES-definedtables*/
/*bit0isleft-mostinbyte*/
staticconstintbytebit[]={
0200,0100,040,020,010,04,02,01
};
/*Setkey(initializekeyschelearray)*/
DES::DES(constbyte*key,CipherDirdir)
:k(32)
{
SecByteBlockbuffer(56+56+8);
byte*constpc1m=buffer;/*placetomodifypc1into*/
byte*constpcr=pc1m+56;/*placetorotatepc1into*/
byte*constks=pcr+56;
registerinti,j,l;
intm;
for(j=0;j<56;j++){/*convertpc1tobitsofkey*/
l=pc1[j]-1;/*integerbitlocation*/
m=l&07;/*findbit*/
pc1m[j]=(key[l>>3]&/*findwhichkeybytelisin*/
bytebit[m])/*andwhichbitofthatbyte*/
?1:0;/*andstore1-bitresult*/
}
for(i=0;i<16;i++){/*keychunkforeachiteration*/
memset(ks,0,8);/*Clearkeyschele*/
for(j=0;j<56;j++)/*rotatepc1therightamount*/
pcr[j]=pc1m[(l=j+totrot[i])<(j<28?28:56)?l:l-28];
/**/
for(j=0;j<48;j++){/*selectbitsindivially*/
/*checkbitthatgoestoks[j]*/
if(pcr[pc2[j]-1]){
/*maskitinifit'sthere*/
l=j%6;
ks[j/6]|=bytebit[l]>>2;
}
}
/*Nowconverttoodd/eveninterleavedformforuseinF*/
k[2*i]=((word32)ks[0]<<24)
|((word32)ks[2]<<16)
|((word32)ks[4]<<8)
|((word32)ks[6]);
k[2*i+1]=((word32)ks[1]<<24)
|((word32)ks[3]<<16)
|((word32)ks[5]<<8)
|((word32)ks[7]);
}
if(dir==DECRYPTION)//reversekeyscheleorder
for(i=0;i<16;i+=2)
{
std::swap(k[i],k[32-2-i]);
std::swap(k[i+1],k[32-1-i]);
}
}
/**/
/*Ccodeonlyinportableversion*/
//RichardOuterbridge'sinitialpermutationalgorithm
/*
inlinevoidIPERM(word32&left,word32&right)
{
word32work;
work=((left>>4)^right)&0x0f0f0f0f;
right^=work;
left^=work<<4;
work=((left>>16)^right)&0xffff;
right^=work;
left^=work<<16;
work=((right>>2)^left)&0x33333333;
left^=work;
right^=(work<<2);
work=((right>>8)^left)&0xff00ff;
left^=work;
right^=(work<<8);
right=rotl(right,1);
work=(left^right)&0xaaaaaaaa;
left^=work;
right^=work;
left=rotl(left,1);
}
inlinevoidFPERM(word32&left,word32&right)
{
word32work;
right=rotr(right,1);
work=(left^right)&0xaaaaaaaa;
left^=work;
right^=work;
left=rotr(left,1);
work=((left>>8)^right)&0xff00ff;
right^=work;
left^=work<<8;
work=((left>>2)^right)&0x33333333;
right^=work;
left^=work<<2;
work=((right>>16)^left)&0xffff;
left^=work;
right^=work<<16;
work=((right>>4)^left)&0x0f0f0f0f;
left^=work;
right^=work<<4;
}
*/
//WeiDai''sinitialpermutation
//algorithm,
//(likeinMSVC)
inlinevoidIPERM(word32&left,word32&right)
{
word32work;
right=rotl(right,4U);
work=(left^right)&0xf0f0f0f0;
left^=work;
right=rotr(right^work,20U);
work=(left^right)&0xffff0000;
left^=work;
right=rotr(right^work,18U);
work=(left^right)&0x33333333;
left^=work;
right=rotr(right^work,6U);
work=(left^right)&0x00ff00ff;
left^=work;
right=rotl(right^work,9U);
work=(left^right)&0xaaaaaaaa;
left=rotl(left^work,1U);
right^=work;
}
inlinevoidFPERM(word32&left,word32&right)
{
word32work;
right=rotr(right,1U);
work=(left^right)&0xaaaaaaaa;
right^=work;
left=rotr(left^work,9U);
work=(left^right)&0x00ff00ff;
right^=work;
left=rotl(left^work,6U);
work=(left^right)&0x33333333;
right^=work;
left=rotl(left^work,18U);
work=(left^right)&0xffff0000;
right^=work;
left=rotl(left^work,20U);
work=(left^right)&0xf0f0f0f0;
right^=work;
left=rotr(left^work,4U);
}
//
voidDES::ProcessBlock(constbyte*inBlock,byte*outBlock)const
{
word32l,r,work;
#ifdefIS_LITTLE_ENDIAN
l=byteReverse(*(word32*)inBlock);
r=byteReverse(*(word32*)(inBlock+4));
#else
l=*(word32*)inBlock;
r=*(word32*)(inBlock+4);
#endif
IPERM(l,r);
constword32*kptr=k;
for(unsignedi=0;i<8;i++)
{
work=rotr(r,4U)^kptr[4*i+0];
l^=Spbox[6][(work)&0x3f]
^Spbox[4][(work>>8)&0x3f]
^Spbox[2][(work>>16)&0x3f]
^Spbox[0][(work>>24)&0x3f];
work=r^kptr[4*i+1];
l^=Spbox[7][(work)&0x3f]
^Spbox[5][(work>>8)&0x3f]
^Spbox[3][(work>>16)&0x3f]
^Spbox[1][(work>>24)&0x3f];
work=rotr(l,4U)^kptr[4*i+2];
r^=Spbox[6][(work)&0x3f]
^Spbox[4][(work>>8)&0x3f]
^Spbox[2][(work>>16)&0x3f]
^Spbox[0][(work>>24)&0x3f];
work=l^kptr[4*i+3];
r^=Spbox[7][(work)&0x3f]
^Spbox[5][(work>>8)&0x3f]
^Spbox[3][(work>>16)&0x3f]
^Spbox[1][(work>>24)&0x3f];
}
FPERM(l,r);
#ifdefIS_LITTLE_ENDIAN
*(word32*)outBlock=byteReverse(r);
*(word32*)(outBlock+4)=byteReverse(l);
#else
*(word32*)outBlock=r;
*(word32*)(outBlock+4)=l;
#endif
}
voidDES_EDE_Encryption::ProcessBlock(byte*inoutBlock)const
{
e.ProcessBlock(inoutBlock);
d.ProcessBlock(inoutBlock);
e.ProcessBlock(inoutBlock);
}
voidDES_EDE_Encryption::ProcessBlock(constbyte*inBlock,byte*outBlock)const
{
e.ProcessBlock(inBlock,outBlock);
d.ProcessBlock(outBlock);
e.ProcessBlock(outBlock);
}
voidDES_EDE_Decryption::ProcessBlock(byte*inoutBlock)const
{
d.ProcessBlock(inoutBlock);
e.ProcessBlock(inoutBlock);
d.ProcessBlock(inoutBlock);
}
voidDES_EDE_Decryption::ProcessBlock(constbyte*inBlock,byte*outBlock)const
{
d.ProcessBlock(inBlock,outBlock);
e.ProcessBlock(outBlock);
d.ProcessBlock(outBlock);
}
voidTripleDES_Encryption::ProcessBlock(byte*inoutBlock)const
{
e1.ProcessBlock(inoutBlock);
d.ProcessBlock(inoutBlock);
e2.ProcessBlock(inoutBlock);
}
voidTripleDES_Encryption::ProcessBlock(constbyte*inBlock,byte*outBlock)const
{
e1.ProcessBlock(inBlock,outBlock);
d.ProcessBlock(outBlock);
e2.ProcessBlock(outBlock);
}
voidTripleDES_Decryption::ProcessBlock(byte*inoutBlock)const
{
d1.ProcessBlock(inoutBlock);
e.ProcessBlock(inoutBlock);
d2.ProcessBlock(inoutBlock);
}
voidTripleDES_Decryption::ProcessBlock(constbyte*inBlock,byte*outBlock)const
{
d1.ProcessBlock(inBlock,outBlock);
e.ProcessBlock(outBlock);
d2.ProcessBlock(outBlock);
}
NAMESPACE_END
程序运行如下:
‘捌’ DES 加密算法是怎样的一种算法要通俗解释..
1977年1月,美国政府颁布:采纳IBM公司设计的方案作为非机密数据的正式数据加密标准(DES枣Data Encryption Standard)。
目前在国内,随着三金工程尤其是金卡工程的启动,DES算法在POS、ATM、磁卡及智能卡(IC卡)、加油站、高速公路收费站等领域被广泛应用,以此来实现关键数据的保密,如信用卡持卡人的PIN的加密传输,IC卡与POS间的双向认证、金融交易数据包的MAC校验等,均用到DES算法。
DES算法的入口参数有三个:Key、Data、Mode。其中Key为8个字节共64位,是DES算法的工作密钥;Data也为8个字节64位,是要被加密或被解密的数据;Mode为DES的工作方式,有两种:加密或解密。
DES算法是这样工作的:如Mode为加密,则用Key 去把数据Data进行加密, 生成Data的密码形式(64位)作为DES的输出结果;如Mode为解密,则用Key去把密码形式的数据Data解密,还原为Data的明码形式(64位)作为DES的输出结果。在通信网络的两端,双方约定一致的Key,在通信的源点用Key对核心数据进行DES加密,然后以密码形式在公共通信网(如电话网)中传输到通信网络的终点,数据到达目的地后,用同样的Key对密码数据进行解密,便再现了明码形式的核心数据。这样,便保证了核心数据(如PIN、MAC等)在公共通信网中传输的安全性和可靠性。
通过定期在通信网络的源端和目的端同时改用新的Key,便能更进一步提高数据的保密性,这正是现在金融交易网络的流行做法。
DES算法详述
DES算法把64位的明文输入块变为64位的密文输出块,它所使用的密钥也是64位,整个算法的主流程图如下:
其功能是把输入的64位数据块按位重新组合,并把输出分为L0、R0两部分,每部分各长32位,其置换规则见下表:
58,50,12,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,
即将输入的第58位换到第一位,第50位换到第2位,...,依此类推,最后一位是原来的第7位。L0、R0则是换位输出后的两部分,L0是输出的左32位,R0 是右32位,例:设置换前的输入值为D1D2D3......D64,则经过初始置换后的结果为:L0=D58D50...D8;R0=D57D49...D7。
经过16次迭代运算后。得到L16、R16,将此作为输入,进行逆置换,即得到密文输出。逆置换正好是初始置的逆运算,例如,第1位经过初始置换后,处于第40位,而通过逆置换,又将第40位换回到第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,
放大换位表
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,
单纯换位表
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,
在f(Ri,Ki)算法描述图中,S1,S2...S8为选择函数,其功能是把6bit数据变为4bit数据。下面给出选择函数Si(i=1,2......8)的功能表:
选择函数Si
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,
在此以S1为例说明其功能,我们可以看到:在S1中,共有4行数据,命名为0,1、2、3行;每行有16列,命名为0、1、2、3,......,14、15列。
现设输入为: D=D1D2D3D4D5D6
令:列=D2D3D4D5
行=D1D6
然后在S1表中查得对应的数,以4位二进制表示,此即为选择函数S1的输出。下面给出子密钥Ki(48bit)的生成算法
从子密钥Ki的生成算法描述图中我们可以看到:初始Key值为64位,但DES算法规定,其中第8、16、......64位是奇偶校验位,不参与DES运算。故Key 实际可用位数便只有56位。即:经过缩小选择换位表1的变换后,Key 的位数由64 位变成了56位,此56位分为C0、D0两部分,各28位,然后分别进行第1次循环左移,得到C1、D1,将C1(28位)、D1(28位)合并得到56位,再经过缩小选择换位2,从而便得到了密钥K0(48位)。依此类推,便可得到K1、K2、......、K15,不过需要注意的是,16次循环左移对应的左移位数要依据下述规则进行:
循环左移位数
1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1
以上介绍了DES算法的加密过程。DES算法的解密过程是一样的,区别仅仅在于第一次迭代时用子密钥K15,第二次K14、......,最后一次用K0,算法本身并没有任何变化。
‘玖’ DES加密算法C语言实现
#include<iostream.h>
class SubKey{ //定义子密钥为一个类
public:
int key[8][6];
}subkey[16]; //定义子密钥对象数组
class DES{
int encipher_decipher; //判断加密还是解密
int key_in[8][8]; //用户原始输入的64位二进制数
int key_out[8][7]; //除去每行的最后一位校验位
int c0_d0[8][7]; //存储经PC-1转换后的56位数据
int c0[4][7],d0[4][7]; //分别存储c0,d0
int text[8][8]; //64位明文
int text_ip[8][8]; //经IP转换过后的明文
int A[4][8],B[4][8]; //A,B分别存储经IP转换过后明文的两部分,便于交换
int temp[8][6]; //存储经扩展置换后的48位二进制值
int temp1[8][6]; //存储和子密钥异或后的结果
int s_result[8][4]; //存储经S变换后的32位值
int text_p[8][4]; //经P置换后的32位结果
int secret_ip[8][8]; //经逆IP转换后的密文
public:
void Key_Putting();
void PC_1();
int function(int,int); //异或
void SubKey_Proction();
void IP_Convert();
void f();
void _IP_Convert();
void Out_secret();
};
void DES::Key_Putting() //得到密钥中对算法有用的56位
{
cout<<"请输入64位的密钥(8行8列且每行都得有奇数个1):\n";
for(int i=0;i<8;i++)
for(int j=0;j<8;j++){
cin>>key_in[i][j];
if(j!=7) key_out[i][j]=key_in[i][j];
}
}
void DES::PC_1() //PC-1置换函数
{
int pc_1[8][7]={ //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}
};
int i,j;
for(i=0;i<8;i++)
for(j=0;j<7;j++)
c0_d0[i][j]=key_out[ (pc_1[i][j]-1)/8 ][ (pc_1[i][j]-1)%8 ];
}
int DES::function(int a,int b) //模拟二进制数的异或运算,a和b为整型的0和1,返回值为整型的0或1
{
if(a!=b)return 1;
else return 0;
}
void DES::SubKey_Proction() //生成子密钥
{
int move[16][2]={ //循环左移的位数
1 , 1 , 2 , 1 ,
3 , 2 , 4 , 2 ,
5 , 2 , 6 , 2 ,
7 , 2 , 8 , 2 ,
9 , 1, 10 , 2,
11 , 2, 12 , 2,
13 , 2, 14 , 2,
15 , 2, 16 , 1
};
int pc_2[8][6]={ //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
};
for(int i=0;i<16;i++) //生成子密钥
{
int j,k;
int a[2],b[2];
int bb[28],cc[28];
for(j=0;j<4;j++)
for(k=0;k<7;k++)
c0[j][k]=c0_d0[j][k];
for(j=4;j<8;j++)
for(k=0;k<7;k++)
d0[j-4][k]=c0_d0[j][k];
for(j=0;j<4;j++)
for(k=0;k<7;k++){
bb[7*j+k]=c0[j][k];
cc[7*j+k]=d0[j][k];
}
for(j=0;j<move[i][1];j++){
a[j]=bb[j];
b[j]=cc[j];
}
for(j=0;j<28-move[i][1];j++){
bb[j]=bb[j+1];
cc[j]=cc[j+1];
}
for(j=0;j<move[i][1];j++){
bb[27-j]=a[j];
cc[27-j]=b[j];
}
for(j=0;j<28;j++){
c0[j/7][j%7]=bb[j];
d0[j/7][j%7]=cc[j];
}
for(j=0;j<4;j++) //L123--L128是把c0,d0合并成c0_d0
for(k=0;k<7;k++)
c0_d0[j][k]=c0[j][k];
for(j=4;j<8;j++)
for(k=0;k<7;k++)
c0_d0[j][k]=d0[j-4][k];
for(j=0;j<8;j++) //对Ci,Di进行PC-2置换
for(k=0;k<6;k++)
subkey[i].key[j][k]=c0_d0[ (pc_2[j][k]-1)/7 ][ (pc_2[j][k]-1)%7 ];
}
}
void DES::IP_Convert()
{
int IP[8][8]={ //初始置换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
};
cout<<"你好,你要加密还是解密?加密请按1号键(输入1),解密请按2号键,并确定."<<'\n';
cin>>encipher_decipher;
char * s;
if(encipher_decipher==1) s="明文";
else s="密文";
cout<<"请输入64位"<<s<<"(二进制):\n";
int i,j;
for(i=0;i<8;i++)
for(j=0;j<8;j++)
cin>>text[i][j];
for(i=0;i<8;i++) //进行IP变换
for(j=0;j<8;j++)
text_ip[i][j]=text[ (IP[i][j]-1)/8 ][ (IP[i][j]-1)%8 ];
}
‘拾’ 用java实现des算法
package des;
import java.io.*;
import java.nio.*;
import java.nio.channels.FileChannel;
public class FileDES{
private static final boolean enc=true; //加密
private static final boolean dec=false; //解密
private String srcFileName;
private String destFileName;
private String inKey;
private boolean actionType;
private File srcFile;
private File destFile;
private Des des;
private void analyzePath(){
String dirName;
int pos=srcFileName.lastIndexOf("/");
dirName=srcFileName.substring(0,pos);
File dir=new File(dirName);
if (!dir.exists()){
System.err.println(dirName+" is not exist");
System.exit(1);
}else if(!dir.isDirectory()){
System.err.println(dirName+" is not a directory");
System.exit(1);
}
pos=destFileName.lastIndexOf("/");
dirName=destFileName.substring(0,pos);
dir=new File(dirName);
if (!dir.exists()){
if(!dir.mkdirs()){
System.out.println ("can not creat directory:"+dirName);
System.exit(1);
}
}else if(!dir.isDirectory()){
System.err.println(dirName+" is not a directory");
System.exit(1);
}
}
private static int replenish(FileChannel channel,ByteBuffer buf) throws IOException{
long byteLeft=channel.size()-channel.position();
if(byteLeft==0L)
return -1;
buf.position(0);
buf.limit(buf.position()+(byteLeft<8 ? (int)byteLeft :8));
return channel.read(buf);
}
private void file_operate(boolean flag){
des=new Des(inKey);
FileOutputStream outputFile=null;
try {
outputFile=new FileOutputStream(srcFile,true);
}catch (java.io.FileNotFoundException e) {
e.printStackTrace(System.err);
}
FileChannel outChannel=outputFile.getChannel();
try{
if(outChannel.size()%2!=0){
ByteBuffer bufTemp=ByteBuffer.allocate(1);
bufTemp.put((byte)32);
bufTemp.flip();
outChannel.position(outChannel.size());
outChannel.write(bufTemp);
bufTemp.clear();
}
}catch(Exception ex){
ex.printStackTrace(System.err);
System.exit(1);
}
FileInputStream inFile=null;
try{
inFile=new FileInputStream(srcFile);
}catch(java.io.FileNotFoundException e){
e.printStackTrace(System.err);
//System.exit(1);
}
outputFile=null;
try {
outputFile=new FileOutputStream(destFile,true);
}catch (java.io.FileNotFoundException e) {
e.printStackTrace(System.err);
}
FileChannel inChannel=inFile.getChannel();
outChannel=outputFile.getChannel();
ByteBuffer inBuf=ByteBuffer.allocate(8);
ByteBuffer outBuf=ByteBuffer.allocate(8);
try{
String srcStr;
String destStr;
while(true){
if (replenish(inChannel,inBuf)==-1) break;
srcStr=((ByteBuffer)(inBuf.flip())).asCharBuffer().toString();
inBuf.clear();
if (flag)
destStr=des.enc(srcStr,srcStr.length());
else
destStr=des.dec(srcStr,srcStr.length());
outBuf.clear();
if (destStr.length()==4){
for (int i = 0; i<4; i++) {
outBuf.putChar(destStr.charAt(i));
}
outBuf.flip();
}else{
outBuf.position(0);
outBuf.limit(2*destStr.length());
for (int i = 0; i<destStr.length(); i++) {
outBuf.putChar(destStr.charAt(i));
}
outBuf.flip();
}
try {
outChannel.write(outBuf);
outBuf.clear();
}catch (java.io.IOException ex) {
ex.printStackTrace(System.err);
}
}
System.out.println (inChannel.size());
System.out.println (outChannel.size());
System.out.println ("EoF reached.");
inFile.close();
outputFile.close();
}catch(java.io.IOException e){
e.printStackTrace(System.err);
System.exit(1);
}
}
public FileDES(String srcFileName,String destFileName,String inKey,boolean actionType){
this.srcFileName=srcFileName;
this.destFileName=destFileName;
this.actionType=actionType;
analyzePath();
srcFile=new File(srcFileName);
destFile=new File(destFileName);
this.inKey=inKey;
if (actionType==enc)
file_operate(enc);
else
file_operate(dec);
}
public static void main(String[] args){
String file1=System.getProperty("user.dir")+"/111.doc";
String file2=System.getProperty("user.dir")+"/222.doc";
String file3=System.getProperty("user.dir")+"/333.doc";
String passWord="1234ABCD";
FileDES fileDes=new FileDES(file1,file2,passWord,true);
FileDES fileDes1=new FileDES(file2,file3,passWord,false);
}