DES、RSA算法实现

刚出炉的代码,网络安全的大作业、、、话说写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;
}

	


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值