刚出炉的代码,网络安全的大作业、、、话说写DES用了两三个小时,但是调试用了一天多有木有啊!!!为什么?我编的是输入字符,结果测试用例用的时十六进制的,,结果一直不对有木有,,代码来回看了好几遍,,中间不断地printf还是找不到问题,然后又把文章读了一遍才发现人家给的是十六进制。。。。。先贴代码,明天把过程补充完整,,现在要复习,,明天考试。。。。。
//DES
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
//S盒
int S1[4][16]={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,
5,12,8,2,4,9,1,7,5,11,3,14,10,0,6,13,};
int S2[4][16]={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};
int S3[4][16]={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};
int S4[4][16]={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};
int S5[4][16]={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};
int S6[4][16]={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};
int S7[4][16]={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};
int S8[4][16]={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 PC1[56]={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 PC2[48]={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};
//对左移次数的规定
int SLS[16]={1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};
//初始置换
int IP[64]={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};
//初始逆置换
int IIP[64]={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};
//扩充置换
int E[48]={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};
//置换函数
int P[32]={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};
void Encrypt(char cha[],char chb[]);
void Experm(char a[],char b[]);
void LeftShift(char a[],char b[],int c);
void PermC2(char a[],char b[],char c[]);
void xor(char a[],char b[],char c[][7]);
void xor1(char a[],char b[],char c[]);
void SBox(char a[],char b[],int c[][16],int d);
void P_Func(char a[],char b[]);
void In_Perm(char a[],char b[],char c[]);
void Ex_Len(char a[],char b[]);
void HexToBin(char a[],char b[]);
void BinToHex(char a[],char b[]);
void Decrypt(char a[],char b[]);
void Produce_K(char a[][49],char b[]);
int main()
{
char plaintext[200]={'\0'};
char ciphertext[200]={'\0'};
char ciphertext1[17]={'\0'};
char plaintext1[17]={'\0'};
char key1[17]={'\0'};
char key[200]={'\0'};
int len;
int i=0;
int n;
while(1)
{
printf("请选择:加密--1;解密--2;退出--0\n");
scanf("%d",&n);
memset(plaintext,0,sizeof(plaintext));
memset(ciphertext,0,sizeof(ciphertext));
memset(key,0,sizeof(key));
if(n==1)
{
printf("please input the plaintext\n");
scanf("%s",plaintext);
printf("please input the key\n");
scanf("%s",key);
//首先对明文及密钥进行处理使其长度均为64的倍数,因为是十六进制,所以数组每个元素代表四位
//另外扩展之后判断密钥长度是否小于明文长度,如果是那么仍需扩展密钥--补零
Ex_Len(plaintext,key);
len=strlen(plaintext);
i=0;
while(16*i!=len)
{
memcpy(plaintext1,plaintext+i*16,16);
memcpy(key1,key+i*16,16);
Encrypt(plaintext1,key1);
i++;
}
}
if(n==2)
{
printf("please input the ciphertext:\n");
scanf("%s",ciphertext);
printf("please input the key:\n");
scanf("%s",key);
//首先处理长度
if(strlen(ciphertext)>strlen(key))
{
len=strlen(key);
for(;strlen(key)<strlen(ciphertext);)
key[len++]='0';
}
len=strlen(ciphertext);
i=0;
while(16*i!=len)
{
memcpy(ciphertext1,ciphertext+i*16,16);
memcpy(key1,key+i*16,16);
Decrypt(ciphertext1,key1);
i++;
}
}
if(n==0)
break;
}
system("pause");
return 0;
}
void Encrypt(char cha[],char chb[])
{
char textbit[65]={'\0'};
char ltext[33]={'\0'};
char rtext[33]={'\0'};
char keybit[65]={'\0'};
char buftext[33]={'\0'};
char extext[49]={'\0'};
char bresult[8][7]={'\0'};
char cresult[33]={'\0'};
char presult[33]={'\0'};
char result[65]={'\0'};
char hex[17]={'\0'};
char key1[16][49]={'\0'};
int i=0,j=0;
//十六进制转换成二进制
HexToBin(textbit,cha);
HexToBin(keybit,chb);
//printf("%s\n",textbit);
//printf("%s\n",keybit);
//进行初始置换
for(i=0;i<32;i++)
ltext[i]=textbit[IP[i]-1];
for(i=32;i<64;i++)
rtext[i-32]=textbit[IP[i]-1];
//printf("%s\n",rtext);
//生成密钥空间
Produce_K(key1,keybit);
//16轮加密
for(i=0;i<16;i++)
{
memcpy(buftext,rtext,32);
//扩充置换
Experm(rtext,extext);
//将密钥和明文进行异或
xor(key1[i],extext,bresult);
// printf("bresult:%s\n",bresult);
//S盒映射6->4
SBox(bresult[0],cresult,S1,0);
//printf("bresult:%s\n",bresult[0]);
//printf("cresult:%s\n",cresult);
SBox(bresult[1],cresult,S2,1);
SBox(bresult[2],cresult,S3,2);
SBox(bresult[3],cresult,S4,3);
SBox(bresult[4],cresult,S5,4);
SBox(bresult[5],cresult,S6,5);
SBox(bresult[6],cresult,S7,6);
SBox(bresult[7],cresult,S8,7);
//进行置换P
P_Func(cresult,presult);
//将左部分和f结果进行异或,结果赋给右部分
xor1(ltext,presult,rtext);
//将原右部分复制给左部分
memcpy(ltext,buftext,32);
//printf("ltext:%s\n",ltext);
//printf("rtext:%s\n",rtext);
}
//合并两部分作逆置换
In_Perm(rtext,ltext,result);
printf("%s\n",result);
//二进制转换成十六进制
BinToHex(result,hex);
printf("%s\n",hex);
}
void Experm(char a[],char b[])
{
int i=0;
for(;i<48;i++)
b[i]=a[E[i]-1];
}
void LeftShift(char a[],char b[],int c)
{
int i;
int j=0;
char t1,t2;
for(;j<SLS[c];j++)
{
t1=a[0];
t2=b[0];
for(i=1;i<28;i++)
{
a[i-1]=a[i];
b[i-1]=b[i];
}
a[27]=t1;
b[27]=t2;
}
}
void PermC2(char a[],char b[],char c[])
{
int i=0;
char t[57]={'\0'};
memcpy(t,a,28);
memcpy(t+28,b,28);
for(;i<56;i++)
c[i]=t[PC2[i]-1];
}
void xor(char a[],char b[],char c[][7])
{
int i=0;
int k=0;
int j=0;
for(;i<48;i++)
{
c[j][(k++)%6]=(a[i]==b[i]?'0':'1');
if(i%6==5)
{
j++;
k=0;
}
}
//printf("ccc:%s\n",c);
}
void Produce_K(char a[][49],char b[])
{
char ckey[29]={'\0'};
char dkey[29]={'\0'};
int i=0;
//密钥进行置换选择1
for(i=0;i<28;i++)
{
ckey[i]=b[PC1[i]-1];
dkey[i]=b[PC1[i+28]-1];
}
for(i=0;i<16;i++)
{
//密钥循环左移
LeftShift(ckey,dkey,i);
//将密钥两部分合并并进行置换选择2
PermC2(ckey,dkey,a[i]);
}
}
void SBox(char a[],char b[],int c[][16],int d)
{
int x;
int y;
int n;
int i=0;
x=(a[0]-'0')*2+(a[5]-'0')*1;;
y=(a[1]-'0')*8+(a[2]-'0')*4+(a[3]-'0')*2+(a[4]-'0')*1;
n=c[x][y];
//printf("c[][]:%d\n",n);
for(i=3;i>=0;i--)
{
b[i+d*4]=(n%2==0?'0':'1');
n/=2;
}
}
void P_Func(char a[],char b[])
{
int i=0;
for(;i<32;i++)
b[i]=a[P[i]-1];
}
void In_Perm(char a[],char b[],char c[])
{
char t[65]={'\0'};
int i=0;
memcpy(t,a,32);
memcpy(t+32,b,32);
for(;i<64;i++)
{
c[i]=t[IIP[i]-1];
}
}
void BittoChar(char a[],char b[])
{
int i=0;
for(;i<4;i++)
{
;
}
}
void xor1(char a[],char b[],char c[])
{
int i=0;
for(;i<32;i++)
c[i]=(a[i]==b[i]?'0':'1');
}
void Ex_Len(char a[],char b[])
{
int la=strlen(a);
int lb=strlen(b);
for(;strlen(a)%16!=0;)
a[la++]='0';
for(;strlen(b)%16!=0;)
b[lb++]='0';
if(strlen(b)<strlen(a))
{
lb=strlen(b);
for(;strlen(b)<strlen(a);)
b[lb++]='0';
}
}
void HexToBin(char a[],char b[])
{
int i=0;
int j;
for(;i<16;i++)
{
if('0'<=b[i]&&b[i]<='9')
{
for(j=3;j>=0;j--)
{
a[i*4+j]=(b[i]-'0')%2+'0';
b[i]=(b[i]-'0')/2+'0';
}
}
else if('a'<=b[i]&&b[i]<='f')
{
for(j=3;j>=0;j--)
{
if('a'<=b[i]&&b[i]<='f')
{
a[i*4+j]=(b[i]-'W')%2+'0';
b[i]=(b[i]-'W')/2+'0';
}
else
{
a[i*4+j]=(b[i]-'0')%2+'0';
b[i]=(b[i]-'0')/2+'0';
}
}
}
}
}
void BinToHex(char a[],char b[])
{
int i=0;
int x;
for(;i<16;i++)
{
x=(a[i*4+0]-'0')*8+(a[i*4+1]-'0')*4+(a[i*4+2]-'0')*2+(a[i*4+3]-'0')*1;
b[i]=(0<=x&&x<=9?(x+'0'):('a'+x-10));
}
}
void Decrypt(char a[],char b[])
{
char textbit[65]={'\0'};
char ltext[33]={'\0'};
char rtext[33]={'\0'};
char keybit[65]={'\0'};
char buftext[33]={'\0'};
char extext[49]={'\0'};
char key1[16][49]={'\0'};
char bresult[8][7]={'\0'};
char cresult[33]={'\0'};
char presult[33]={'\0'};
char result[65]={'\0'};
char hex[17]={'\0'};
int i=0,j=0;
//十六进制转换成二进制
HexToBin(textbit,a);
HexToBin(keybit,b);
//printf("%s\n",textbit);
//printf("%s\n",keybit);
//进行初始置换
for(i=0;i<32;i++)
ltext[i]=textbit[IP[i]-1];
for(i=32;i<64;i++)
rtext[i-32]=textbit[IP[i]-1];
//printf("%s\n",rtext);
Produce_K(key1,keybit);
//16轮加密
for(i=0;i<16;i++)
{
memcpy(buftext,rtext,32);
//扩充置换
Experm(rtext,extext);
//将密钥和明文进行异或
xor(key1[15-i],extext,bresult);
// printf("bresult:%s\n",bresult);
//S盒映射6->4
SBox(bresult[0],cresult,S1,0);
//printf("bresult:%s\n",bresult[0]);
//printf("cresult:%s\n",cresult);
SBox(bresult[1],cresult,S2,1);
SBox(bresult[2],cresult,S3,2);
SBox(bresult[3],cresult,S4,3);
SBox(bresult[4],cresult,S5,4);
SBox(bresult[5],cresult,S6,5);
SBox(bresult[6],cresult,S7,6);
SBox(bresult[7],cresult,S8,7);
//进行置换P
P_Func(cresult,presult);
//将左部分和f结果进行异或,结果赋给右部分
xor1(ltext,presult,rtext);
//将原右部分复制给左部分
memcpy(ltext,buftext,32);
//printf("ltext:%s\n",ltext);
//printf("rtext:%s\n",rtext);
}
//合并两部分作逆置换
In_Perm(rtext,ltext,result);
printf("%s\n",result);
//二进制转换成十六进制
BinToHex(result,hex);
printf("%s\n",hex);
}
//RSA
#include <stdio.h>
#include <stdlib.h>
long int privatekey(long int a,long int b);
long int ToBin(int a[],long int b);
long int comput(long int a,long int b,long int c);
long int Hash(char a[]);
int main()
{
long int p,q;
long int n;
long int N;
long int e,d;
long int m,M;
char msg[50];
long int hash;
long int hash1;
while(1)
{
memset(msg,0,50);
printf("输入两个素数:\n");
scanf("%ld%ld",&p,&q);
n=p*q;
N=(p-1)*(q-1);
printf("输入公钥:\n");
scanf("%ld",&e);
d=privatekey(N,e);
printf("私钥为:%ld\n",d);
printf("输入明文:\n");
scanf("%ld",&m);
M=comput(m,e,n);
printf("用公钥加密后为:%ld\n",M);
printf("用私钥解密后为:%ld\n",comput(M,d,n));
printf("数字签名:\n");
printf("输入一段消息:");
scanf("%s",msg);
//进行hash,ELF算法
hash=Hash(msg);
printf("HASH值为:%ld\n",hash);
printf("用自己的私钥加密:\n");
M=comput(hash,d,n);
printf("结果为:%ld\n",M);
printf("用发送方的公钥解密:\n");
m=comput(M,e,n);
printf("结果为:%ld\n",m);
printf("开始模拟验证:\n");
printf("正确情况相况下:\n");
hash1=Hash(msg);
if(hash1==m)
printf("正确\n");
else
printf("错误\n");
printf("错误情况下(在原消息后添加一字符):\n");
msg[strlen(msg)]='q';
hash1=Hash(msg);
printf("修改后的HASH值为:%ld\n",hash1);
if(hash1==m)
printf("正确\n");
else
printf("错误\n");
}
system("pause");
return 0;
}
long int privatekey(long int a,long int b)
{
long int r[100],q[100],x[100],y[100];
long int i=0;
r[0]=a;r[1]=b;q[0]=q[1]=0;
x[0]=1;x[1]=0;y[0]=0;y[1]=1;
for(i=2;;i++)
{
r[i]=r[i-2]%r[i-1];
if(!r[i])
break;
q[i]=r[i-2]/r[i-1];
x[i]=x[i-2]-q[i]*x[i-1];
y[i]=y[i-2]-q[i]*y[i-1];
}
if(y[i-1]<0)
y[i-1]=r[0]+y[i-1];
return y[i-1];
}
long int ToBin(int a[],long int b)
{
int i=0;
for(;;)
{
a[i++]=b%2;
b/=2;
if(!b)
break;
}
return i;
}
long int comput(long int a,long int b,long int c)
{
int binary[100];
long int k;
int i;long int f=1;
k=ToBin(binary,b);
for(i=k-1;i>=0;i--)
{
f=(f*f)%c;
if(binary[i]==1)
f=(f*a)%c;
}
return f;
}
long int Hash(char a[])
{
long int hash=0;
int i=0;
long int x=0;
for(;i<strlen(a);i++)
{
hash=(hash<<4)+a[i];
if((x=hash&0xF0000000L)!=0)
hash^=(x>>24);
hash&=~x;
}
return hash;
}