⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 des.c

📁 DES加密算法的一种实现,可以用于加密芯片,IC卡的加密解密和认证应用.
💻 C
字号:
#include "string.h"
//---------------------------------------------------------------------------

unsigned char sboxvalue[8][4*16]={
   0xe,0x4,0xd,0x1,0x2,0xf,0xb,0x8,0x3,0xa,0x6,0xc,0x5,0x9,0x0,0x7,
   0x0,0xf,0x7,0x4,0xe,0x2,0xd,0x1,0xa,0x6,0xc,0xb,0x9,0x5,0x3,0x8,
   0x4,0x1,0xe,0x8,0xd,0x6,0x2,0xb,0xf,0xc,0x9,0x7,0x3,0xa,0x5,0x0,
   0xf,0xc,0x8,0x2,0x4,0x9,0x1,0x7,0x5,0xb,0x3,0xe,0xa,0x0,0x6,0xd,

   0xf,0x1,0x8,0xe,0x6,0xb,0x3,0x4,0x9,0x7,0x2,0xd,0xc,0x0,0x5,0xa,
   0x3,0xd,0x4,0x7,0xf,0x2,0x8,0xe,0xc,0x0,0x1,0xa,0x6,0x9,0xb,0x5,
   0x0,0xe,0x7,0xb,0xa,0x4,0xd,0x1,0x5,0x8,0xc,0x6,0x9,0x3,0x2,0xf,
   0xd,0x8,0xa,0x1,0x3,0xf,0x4,0x2,0xb,0x6,0x7,0xc,0x0,0x5,0xe,0x9,

   0xa,0x0,0x9,0xe,0x6,0x3,0xf,0x5,0x1,0xd,0xc,0x7,0xb,0x4,0x2,0x8,
   0xd,0x7,0x0,0x9,0x3,0x4,0x6,0xa,0x2,0x8,0x5,0xe,0xc,0xb,0xf,0x1,
   0xd,0x6,0x4,0x9,0x8,0xf,0x3,0x0,0xb,0x1,0x2,0xc,0x5,0xa,0xe,0x7,
   0x1,0xa,0xd,0x0,0x6,0x9,0x8,0x7,0x4,0xf,0xe,0x3,0xb,0x5,0x2,0xc,

   0x7,0xd,0xe,0x3,0x0,0x6,0x9,0xa,0x1,0x2,0x8,0x5,0xb,0xc,0x4,0xf,
   0xd,0x8,0xb,0x5,0x6,0xf,0x0,0x3,0x4,0x7,0x2,0xc,0x1,0xa,0xe,0x9,
   0xa,0x6,0x9,0x0,0xc,0xb,0x7,0xd,0xf,0x1,0x3,0xe,0x5,0x2,0x8,0x4,
   0x3,0xf,0x0,0x6,0xa,0x1,0xd,0x8,0x9,0x4,0x5,0xb,0xc,0x7,0x2,0xe,

   0x2,0xc,0x4,0x1,0x7,0xa,0xb,0x6,0x8,0x5,0x3,0xf,0xd,0x0,0xe,0x9,
   0xe,0xb,0x2,0xc,0x4,0x7,0xd,0x1,0x5,0x0,0xf,0xa,0x3,0x9,0x8,0x6,
   0x4,0x2,0x1,0xb,0xa,0xd,0x7,0x8,0xf,0x9,0xc,0x5,0x6,0x3,0x0,0xe,
   0xb,0x8,0xc,0x7,0x1,0xe,0x2,0xd,0x6,0xf,0x0,0x9,0xa,0x4,0x5,0x3,

   0xc,0x1,0xa,0xf,0x9,0x2,0x6,0x8,0x0,0xd,0x3,0x4,0xe,0x7,0x5,0xb,
   0xa,0xf,0x4,0x2,0x7,0xc,0x9,0x5,0x6,0x1,0xd,0xe,0x0,0xb,0x3,0x8,
   0x9,0xe,0xf,0x5,0x2,0x8,0xc,0x3,0x7,0x0,0x4,0xa,0x1,0xd,0xb,0x6,
   0x4,0x3,0x2,0xc,0x9,0x5,0xf,0xa,0xb,0xe,0x1,0x7,0x6,0x0,0x8,0xd,

   0x4,0xb,0x2,0xe,0xf,0x0,0x8,0xd,0x3,0xc,0x9,0x7,0x5,0xa,0x6,0x1,
   0xd,0x0,0xb,0x7,0x4,0x9,0x1,0xa,0xe,0x3,0x5,0xc,0x2,0xf,0x8,0x6,
   0x1,0x4,0xb,0xd,0xc,0x3,0x7,0xe,0xa,0xf,0x6,0x8,0x0,0x5,0x9,0x2,
   0x6,0xb,0xd,0x8,0x1,0x4,0xa,0x7,0x9,0x5,0x0,0xf,0xe,0x2,0x3,0xc,
   
   0xd,0x2,0x8,0x4,0x6,0xf,0xb,0x1,0xa,0x9,0x3,0xe,0x5,0x0,0xc,0x7,
   0x1,0xf,0xd,0x8,0xa,0x3,0x7,0x4,0xc,0x5,0x6,0xb,0x0,0xe,0x9,0x2,
   0x7,0xb,0x4,0x1,0x9,0xc,0xe,0x2,0x0,0x6,0xa,0xd,0xf,0x3,0x5,0x8,
   0x2,0x1,0xe,0x7,0x4,0xa,0x8,0xd,0xf,0xc,0x9,0x0,0x3,0x5,0x6,0xb,
};


void BitsToByte(unsigned char *bitstr,unsigned char *bytechar)
{
   register i;
   unsigned char tmpchar,tmpstr[8];

   tmpchar=0;
   memcpy(tmpstr,bitstr,8);
   for (i=0;i<8;i++) tmpstr[i]=tmpstr[i]&0x01;  //clear high 7 bit
   for (i=0;i<7;i++) {
      tmpchar=tmpchar|tmpstr[i];
      tmpchar=tmpchar<<1;
   }
   tmpchar=tmpchar|tmpstr[7];

   *bytechar=tmpchar;
}

void ByteToBits(unsigned char bytechar,unsigned char *bitstr)
{
   register i;
   unsigned char tmpchar;

   tmpchar=bytechar;
   for (i=7;i>=0;i--) {
      bitstr[i]=tmpchar&0x01;
      tmpchar=tmpchar>>1;
   }
}

void Permute_IP(unsigned char *text,unsigned char *text_ip)
//对明文做初始置换
//text-明文,长度为8字节;test_ip-置换后的明文,长度为8字节
{
   unsigned char byte_text[64],byte_ip_text[64];
   register i,j;

   memset(byte_text,0,64);
   memset(byte_ip_text,0,64);
   for (i=0;i<8;i++) ByteToBits(text[i],byte_text+i*8);

   for (i=0;i<4;i++) {
      for (j=0;j<8;j++) {
         byte_ip_text[i*8+j]=byte_text[(7-j)*8+i*2+1];
      }
   }

   for (i=4;i<8;i++) {
      for (j=0;j<8;j++) {
         byte_ip_text[i*8+j]=byte_text[(7-j)*8+(i-4)*2];
      }
   }

   for (i=0;i<8;i++) BitsToByte(byte_ip_text+i*8,&text_ip[i]);
}

//逆初始置换
void Reverse_IP(unsigned char *ip_text,unsigned char *text)
{
   unsigned char byte_ip_text[64],byte_text[64];
   register i,j;

   memset(byte_text,0,64);
   memset(byte_ip_text,0,64);
   for (i=0;i<8;i++) ByteToBits(ip_text[i],byte_ip_text+i*8);

   for (i=0;i<8;i++) {
      for (j=0;j<4;j++) {
         byte_text[i*8+j*2]=byte_ip_text[(j+4)*8+(7-i)];
      }
   }

   for (i=0;i<8;i++) {
      for (j=0;j<4;j++) {
         byte_text[i*8+j*2+1]=byte_ip_text[j*8+(7-i)];
      }
   }

   for (i=0;i<8;i++) BitsToByte(byte_text+i*8,&text[i]);
}

void MoveLeft(unsigned char *buff)
{
   register i;
   unsigned char tmpchar;

   tmpchar=buff[0];
   for (i=0;i<27;i++) buff[i]=buff[i+1];
   buff[27]=tmpchar;
}

//用原始密码(64位)产生一组48位的子密钥Ki,1<=i<=16
void GetCircleKey(unsigned char *inkey,unsigned char *outkey)
{
   register i,j;
   unsigned char keybuff[64];
   unsigned char c0[28],d0[28];
   unsigned char ki_buff[48];

   for (i=0;i<8;i++) ByteToBits(inkey[i],keybuff+i*8);

   //得到C0
   for (i=0;i<3;i++) {
      for (j=0;j<8;j++) {
         c0[i*8+j]=keybuff[(7-j)*8+i];
      }
   }
   c0[24]=keybuff[59];
   c0[25]=keybuff[51];
   c0[26]=keybuff[43];
   c0[27]=keybuff[35];

   //得到D0
   for (i=0;i<3;i++) {
      for (j=0;j<8;j++) {
         d0[i*8+j]=keybuff[(7-j)*8+(6-i)];
      }
   }
   d0[24]=keybuff[27];
   d0[25]=keybuff[19];
   d0[26]=keybuff[11];
   d0[27]=keybuff[3];

   //得到16个48位的子密钥
   for (i=0;i<16;i++) {
      switch (i) {
         case 0:
         case 1:
         case 8:
         case 15:
            MoveLeft(c0);
            MoveLeft(d0);
            break;
         default:
            MoveLeft(c0);
            MoveLeft(c0);
            MoveLeft(d0);
            MoveLeft(d0);
            break;
      }

      ki_buff[0]=c0[13];
      ki_buff[1]=c0[16];
      ki_buff[2]=c0[10];
      ki_buff[3]=c0[23];
      ki_buff[4]=c0[0];
      ki_buff[5]=c0[4];

      ki_buff[6]=c0[2];
      ki_buff[7]=c0[27];
      ki_buff[8]=c0[14];
      ki_buff[9]=c0[5];
      ki_buff[10]=c0[20];
      ki_buff[11]=c0[9];

      ki_buff[12]=c0[22];
      ki_buff[13]=c0[18];
      ki_buff[14]=c0[11];
      ki_buff[15]=c0[3];
      ki_buff[16]=c0[25];
      ki_buff[17]=c0[7];

      ki_buff[18]=c0[15];
      ki_buff[19]=c0[6];
      ki_buff[20]=c0[26];
      ki_buff[21]=c0[19];
      ki_buff[22]=c0[12];
      ki_buff[23]=c0[1];

      ki_buff[24]=d0[12];
      ki_buff[25]=d0[23];
      ki_buff[26]=d0[2];
      ki_buff[27]=d0[8];
      ki_buff[28]=d0[18];
      ki_buff[29]=d0[26];

      ki_buff[30]=d0[1];
      ki_buff[31]=d0[11];
      ki_buff[32]=d0[22];
      ki_buff[33]=d0[16];
      ki_buff[34]=d0[4];
      ki_buff[35]=d0[19];

      ki_buff[36]=d0[15];
      ki_buff[37]=d0[20];
      ki_buff[38]=d0[10];
      ki_buff[39]=d0[27];
      ki_buff[40]=d0[5];
      ki_buff[41]=d0[24];

      ki_buff[42]=d0[17];
      ki_buff[43]=d0[13];
      ki_buff[44]=d0[21];
      ki_buff[45]=d0[7];
      ki_buff[46]=d0[0];
      ki_buff[47]=d0[3];

      for (j=0;j<6;j++) BitsToByte(ki_buff+8*j,&outkey[i*6+j]);
   }
}

//选择运算E,对32位变量进行操作,产生48位输出
void Select_E(unsigned char *str32,unsigned char *str48)
{
   unsigned char in_buff[33],out_buff[48];
   register i,j;

   for (i=0;i<4;i++) ByteToBits(str32[i],in_buff+i*8);

   for (i=0;i<8;i++) {
      for (j=0;j<2;j++)
         if (i!=0) out_buff[i*6+j]=in_buff[i*4+j-1];
      for (j=2;j<6;j++) out_buff[i*6+j]=in_buff[i*4+j-1];
   }
   out_buff[0]=in_buff[31];
   out_buff[1]=in_buff[0];
   out_buff[47]=in_buff[0];

   for (i=0;i<6;i++) BitsToByte(out_buff+i*8,&str48[i]);
}


//通过选择函数Si把48位结果变成32位输出
void Select_Si(unsigned char *str48,unsigned char *str32)
{
   register i;
   unsigned char buff48[48],buff[8],tmpchar;
   int x,y;

   for (i=0;i<6;i++) ByteToBits(str48[i],buff48+i*8);

   for (i=0;i<8;i++) {
      x=buff48[i*6]*2+buff48[i*6+5];
      y=buff48[i*6+1]*8+buff48[i*6+2]*4+buff48[i*6+3]*2+buff48[i*6+4];
      tmpchar=sboxvalue[i][x*16+y];
      buff[i]=tmpchar;
   }

   for (i=0;i<4;i++) {
      tmpchar=((buff[i*2]<<4)&0xf0)+(buff[i*2+1]&0x0f);
      str32[i]=tmpchar;
   }
}

//对32位数据做P置换
void Permute_P(unsigned char *text,unsigned char *text_p)
{
   unsigned char byte_text[32],byte_p_text[32];
   register i;

   memset(byte_text,0,32);
   memset(byte_p_text,0,32);
   for (i=0;i<4;i++) ByteToBits(text[i],byte_text+i*8);

   byte_p_text[0]=byte_text[15];
   byte_p_text[1]=byte_text[6];
   byte_p_text[2]=byte_text[19];
   byte_p_text[3]=byte_text[20];

   byte_p_text[4]=byte_text[28];
   byte_p_text[5]=byte_text[11];
   byte_p_text[6]=byte_text[27];
   byte_p_text[7]=byte_text[16];

   byte_p_text[8]=byte_text[0];
   byte_p_text[9]=byte_text[14];
   byte_p_text[10]=byte_text[22];
   byte_p_text[11]=byte_text[25];

   byte_p_text[12]=byte_text[4];
   byte_p_text[13]=byte_text[17];
   byte_p_text[14]=byte_text[30];
   byte_p_text[15]=byte_text[9];

   byte_p_text[16]=byte_text[1];
   byte_p_text[17]=byte_text[7];
   byte_p_text[18]=byte_text[23];
   byte_p_text[19]=byte_text[13];

   byte_p_text[20]=byte_text[31];
   byte_p_text[21]=byte_text[26];
   byte_p_text[22]=byte_text[2];
   byte_p_text[23]=byte_text[8];

   byte_p_text[24]=byte_text[18];
   byte_p_text[25]=byte_text[12];
   byte_p_text[26]=byte_text[29];
   byte_p_text[27]=byte_text[5];

   byte_p_text[28]=byte_text[21];
   byte_p_text[29]=byte_text[10];
   byte_p_text[30]=byte_text[3];
   byte_p_text[31]=byte_text[24];

   for (i=0;i<4;i++) BitsToByte(byte_p_text+i*8,&text_p[i]);
}


//DES加密运算
//plain_text-明文,8个字节;key_text-密钥,8个字节;encrypt_text-密文,8个字节
void DES_encrypt(unsigned char *plain_text,unsigned char *key_text,unsigned char *encrypt_text)
{
   register i,j;
   unsigned char key16[16*6]; //存放16个48位子密钥
   unsigned char plain_ip[8],tmpbuff[4],buff48[6],tmp32[4];

   //初始置换
   Permute_IP(plain_text,plain_ip);

   //得到16个子密钥
   GetCircleKey(key_text,key16);

   for (i=0;i<16;i++) {
      memcpy(tmpbuff,plain_ip+4,4); //L(i)=R(i-1)
      Select_E(plain_ip+4,buff48);  
      for (j=0;j<6;j++) buff48[j]=buff48[j]^key16[i*6+j];  //48位模2加
      Select_Si(buff48,tmp32);     
      Permute_P(tmp32,buff48);      //P置换
      memcpy(tmp32,buff48,4);
      for (j=0;j<4;j++) buff48[j]=tmp32[j]^plain_ip[j]; //32位模2加
      memcpy(plain_ip,tmpbuff,4);          //L(i)
      memcpy(plain_ip+4,buff48,4);          //R(i)
   }

   //码组交换
   memcpy(tmpbuff,plain_ip+4,4);
   memcpy(plain_ip+4,plain_ip,4);
   memcpy(plain_ip,tmpbuff,4);

   Reverse_IP(plain_ip,encrypt_text);
}

//DES解密运算
//encrypt_text-密文,8个字节;key_text-密钥,8个字节;plain_text-明文,8个字节
void DES_decrypt(unsigned char *encrypt_text,unsigned char *key_text,unsigned char *plain_text)
{
   register i,j;
   unsigned char key16[16*6]; //存放16个48位子密钥
   unsigned char plain_ip[8],tmpbuff[4],buff48[6],tmp32[4];

   //初始置换
   Permute_IP(encrypt_text,plain_ip);

   //得到16个子密钥
   GetCircleKey(key_text,key16);

  
   for (i=15;i>=0;i--) {
      memcpy(tmpbuff,plain_ip+4,4); //R(i-1)=L(i)
      Select_E(plain_ip+4,buff48);  
      for (j=0;j<6;j++) buff48[j]=buff48[j]^key16[i*6+j];  //48位模2加
      Select_Si(buff48,tmp32);     
      Permute_P(tmp32,buff48);      //P置换
      memcpy(tmp32,buff48,4);
      for (j=0;j<4;j++) buff48[j]=tmp32[j]^plain_ip[j]; //32位模2加
      memcpy(plain_ip,tmpbuff,4);          //L(i)
      memcpy(plain_ip+4,buff48,4);          //R(i)
   }
   memcpy(tmpbuff,plain_ip+4,4);
   memcpy(plain_ip+4,plain_ip,4);
   memcpy(plain_ip,tmpbuff,4);

   Reverse_IP(plain_ip,plain_text);
}

void DES3_encrypt(unsigned char *plain_text,unsigned char *key_text,unsigned char *encrypt_text)
{
   unsigned char left_key[8],right_key[8];
   unsigned char encrypt1[8],encrypt2[8];

   memset(left_key,0,8);
   memset(right_key,0,8);
   memset(encrypt1,0,8);
   memset(encrypt2,0,8);
   memcpy(left_key,key_text,8);
   memcpy(right_key,key_text+8,8);

   DES_encrypt(plain_text,left_key,encrypt1);
   DES_decrypt(encrypt1,right_key,encrypt2);
   DES_encrypt(encrypt2,left_key,encrypt_text);
   return;
}

void DES3_decrypt(unsigned char *encrypt_text,unsigned char *key_text,unsigned char *plain_text)
{
   unsigned char left_key[8],right_key[8];
   unsigned char encrypt1[8],encrypt2[8];

   memset(left_key,0,8);
   memset(right_key,0,8);
   memset(encrypt1,0,8);
   memset(encrypt2,0,8);
   memcpy(left_key,key_text,8);
   memcpy(right_key,key_text+8,8);

   DES_decrypt(encrypt_text,left_key,encrypt1);
   DES_encrypt(encrypt1,right_key,encrypt2);
   DES_decrypt(encrypt2,left_key,plain_text);
   return;
}

void main()
{
int i;
unsigned char MK[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};  
unsigned char SN[8]={0xEF,0xA8,0xBD,0xA2,0xF5,0xFE,0xB6,0xB2};

unsigned char CSK[8];

unsigned char RD[8];
unsigned char Y[8];

DES_encrypt(SN,MK,CSK);                  //CSK=DES(MK,S/N)
printf("CSK: 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x \n",CSK[0],CSK[1],CSK[2],CSK[3],CSK[4],CSK[5],CSK[6],CSK[7]);

for( i=0;i<8;i++)					     //产生随机数
        RD[i] = (char)rand();
printf("RAND: 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x \n",RD[0],RD[1],RD[2],RD[3],RD[4],RD[5],RD[6],RD[7]);
	
DES_encrypt(RD,CSK,Y);               
printf("Y: 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x \n",Y[0],Y[1],Y[2],Y[3],Y[4],Y[5],Y[6],Y[7]);

//DES_decrypt(Y,CSK,RD)
//printf("RAND: 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x \n",RD[0],RD[1],RD[2],RD[3],RD[4],RD[5],RD[6],RD[7]);
getchar();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -