2种现代密码算法的设计与实现——C++

  • 2种现代密码
    • 1.MD5算法
      • 代码
      • 结果
    • 2.DES算法
      • 代码
      • 结果

本文将介绍两种现代密码算法并进行代码实现:

  1. 使用 C++ 实现2种现代密码算法
  2. 明文:I am a student

2种现代密码

1.MD5算法

MD5是输入不定长度信息,输出固定长度128-bits的算法。经过程序流程,生成四个32位数据,最后联合起来成为一个128-bits散列。基本方式为,求余、取余、调整长度、与链接变量进行循环运算。得出结果。

第一步、填充:如果输入信息的长度(bit)对512求余的结果不等于448,就需要填充使得对512求余的结果等于448。填充的方法是填充一个1和n个0。填充完后,信息的长度就为N512+448(bit);
第二步、记录信息长度:用64位来存储填充前信息长度。这64位加在第一步结果的后面,这样信息长度就变为N
512+448+64=(N+1)*512位。
第三步、装入标准的幻数(四个整数):标准的幻数(物理顺序)是(A=(01234567)16,B=(89ABCDEF)16,C=(FEDCBA98)16,D=(76543210)16)。如果在程序中定义应该是:
(A=0X67452301L,B=0XEFCDAB89L,C=0X98BADCFEL,D=0X10325476L)。
第四步、四轮循环运算:循环的次数是分组的个数(N+1)

代码

MD5.h

#ifndef MD5_h
#define MD5_htypedef struct
{unsigned int count[2];unsigned int state[4];unsigned char buffer[64];
}MD5_CTX;#define F(x,y,z) ((x & y) | (~x & z))
#define G(x,y,z) ((x & z) | (y & ~z))
#define H(x,y,z) (x^y^z)
#define I(x,y,z) (y ^ (x | ~z))
#define ROTATE_LEFT(x,n) ((x << n) | (x >> (32-n)))
#define FF(a,b,c,d,x,s,ac) \
{ \a += F(b,c,d) + x + ac; \a = ROTATE_LEFT(a,s); \a += b; \
}
#define GG(a,b,c,d,x,s,ac) \
{ \a += G(b,c,d) + x + ac; \a = ROTATE_LEFT(a,s); \a += b; \
}
#define HH(a,b,c,d,x,s,ac) \
{ \a += H(b,c,d) + x + ac; \a = ROTATE_LEFT(a,s); \a += b; \
}
#define II(a,b,c,d,x,s,ac) \
{ \a += I(b,c,d) + x + ac; \a = ROTATE_LEFT(a,s); \a += b; \
}
void MD5Init(MD5_CTX *context);
void MD5Update(MD5_CTX *context,unsigned char *input,unsigned int inputlen);
void MD5Final(MD5_CTX *context,unsigned char digest[16]);
void MD5Transform(unsigned int state[4],unsigned char block[64]);
void MD5Encode(unsigned char *output,unsigned int *input,unsigned int len);
void MD5Decode(unsigned int *output,unsigned char *input,unsigned int len);#endif /* MD5_h */

main.cpp

#include <stdio.h>
#include <memory.h>
#include "MD5.h"unsigned char PADDING[]={0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};void MD5Init(MD5_CTX *context)
{context->count[0] = 0;context->count[1] = 0;context->state[0] = 0x67452301;context->state[1] = 0xEFCDAB89;context->state[2] = 0x98BADCFE;context->state[3] = 0x10325476;
}
void MD5Update(MD5_CTX *context,unsigned char *input,unsigned int inputlen)
{unsigned int i = 0,index = 0,partlen = 0;index = (context->count[0] >> 3) & 0x3F;partlen = 64 - index;context->count[0] += inputlen << 3;if(context->count[0] < (inputlen << 3))context->count[1]++;context->count[1] += inputlen >> 29;if(inputlen >= partlen){memcpy(&context->buffer[index],input,partlen);MD5Transform(context->state,context->buffer);for(i = partlen;i+64 <= inputlen;i+=64)MD5Transform(context->state,&input[i]);index = 0;}else{i = 0;}memcpy(&context->buffer[index],&input[i],inputlen-i);
}
void MD5Final(MD5_CTX *context,unsigned char digest[16])
{unsigned int index = 0,padlen = 0;unsigned char bits[8];index = (context->count[0] >> 3) & 0x3F;padlen = (index < 56)?(56-index):(120-index);MD5Encode(bits,context->count,8);MD5Update(context,PADDING,padlen);MD5Update(context,bits,8);MD5Encode(digest,context->state,16);
}
void MD5Encode(unsigned char *output,unsigned int *input,unsigned int len)
{unsigned int i = 0,j = 0;while(j < len){output[j] = input[i] & 0xFF;output[j+1] = (input[i] >> 8) & 0xFF;output[j+2] = (input[i] >> 16) & 0xFF;output[j+3] = (input[i] >> 24) & 0xFF;i++;j+=4;}
}
void MD5Decode(unsigned int *output,unsigned char *input,unsigned int len)
{unsigned int i = 0,j = 0;while(j < len){output[i] = (input[j]) |(input[j+1] << 8) |(input[j+2] << 16) |(input[j+3] << 24);i++;j+=4;}
}
void MD5Transform(unsigned int state[4],unsigned char block[64])
{unsigned int a = state[0];unsigned int b = state[1];unsigned int c = state[2];unsigned int d = state[3];unsigned int x[64];MD5Decode(x,block,64);FF(a, b, c, d, x[ 0], 7, 0xd76aa478); /* 1 */FF(d, a, b, c, x[ 1], 12, 0xe8c7b756); /* 2 */FF(c, d, a, b, x[ 2], 17, 0x242070db); /* 3 */FF(b, c, d, a, x[ 3], 22, 0xc1bdceee); /* 4 */FF(a, b, c, d, x[ 4], 7, 0xf57c0faf); /* 5 */FF(d, a, b, c, x[ 5], 12, 0x4787c62a); /* 6 */FF(c, d, a, b, x[ 6], 17, 0xa8304613); /* 7 */FF(b, c, d, a, x[ 7], 22, 0xfd469501); /* 8 */FF(a, b, c, d, x[ 8], 7, 0x698098d8); /* 9 */FF(d, a, b, c, x[ 9], 12, 0x8b44f7af); /* 10 */FF(c, d, a, b, x[10], 17, 0xffff5bb1); /* 11 */FF(b, c, d, a, x[11], 22, 0x895cd7be); /* 12 */FF(a, b, c, d, x[12], 7, 0x6b901122); /* 13 */FF(d, a, b, c, x[13], 12, 0xfd987193); /* 14 */FF(c, d, a, b, x[14], 17, 0xa679438e); /* 15 */FF(b, c, d, a, x[15], 22, 0x49b40821); /* 16 *//* Round 2 */GG(a, b, c, d, x[ 1], 5, 0xf61e2562); /* 17 */GG(d, a, b, c, x[ 6], 9, 0xc040b340); /* 18 */GG(c, d, a, b, x[11], 14, 0x265e5a51); /* 19 */GG(b, c, d, a, x[ 0], 20, 0xe9b6c7aa); /* 20 */GG(a, b, c, d, x[ 5], 5, 0xd62f105d); /* 21 */GG(d, a, b, c, x[10], 9,  0x2441453); /* 22 */GG(c, d, a, b, x[15], 14, 0xd8a1e681); /* 23 */GG(b, c, d, a, x[ 4], 20, 0xe7d3fbc8); /* 24 */GG(a, b, c, d, x[ 9], 5, 0x21e1cde6); /* 25 */GG(d, a, b, c, x[14], 9, 0xc33707d6); /* 26 */GG(c, d, a, b, x[ 3], 14, 0xf4d50d87); /* 27 */GG(b, c, d, a, x[ 8], 20, 0x455a14ed); /* 28 */GG(a, b, c, d, x[13], 5, 0xa9e3e905); /* 29 */GG(d, a, b, c, x[ 2], 9, 0xfcefa3f8); /* 30 */GG(c, d, a, b, x[ 7], 14, 0x676f02d9); /* 31 */GG(b, c, d, a, x[12], 20, 0x8d2a4c8a); /* 32 *//* Round 3 */HH(a, b, c, d, x[ 5], 4, 0xfffa3942); /* 33 */HH(d, a, b, c, x[ 8], 11, 0x8771f681); /* 34 */HH(c, d, a, b, x[11], 16, 0x6d9d6122); /* 35 */HH(b, c, d, a, x[14], 23, 0xfde5380c); /* 36 */HH(a, b, c, d, x[ 1], 4, 0xa4beea44); /* 37 */HH(d, a, b, c, x[ 4], 11, 0x4bdecfa9); /* 38 */HH(c, d, a, b, x[ 7], 16, 0xf6bb4b60); /* 39 */HH(b, c, d, a, x[10], 23, 0xbebfbc70); /* 40 */HH(a, b, c, d, x[13], 4, 0x289b7ec6); /* 41 */HH(d, a, b, c, x[ 0], 11, 0xeaa127fa); /* 42 */HH(c, d, a, b, x[ 3], 16, 0xd4ef3085); /* 43 */HH(b, c, d, a, x[ 6], 23,  0x4881d05); /* 44 */HH(a, b, c, d, x[ 9], 4, 0xd9d4d039); /* 45 */HH(d, a, b, c, x[12], 11, 0xe6db99e5); /* 46 */HH(c, d, a, b, x[15], 16, 0x1fa27cf8); /* 47 */HH(b, c, d, a, x[ 2], 23, 0xc4ac5665); /* 48 *//* Round 4 */II(a, b, c, d, x[ 0], 6, 0xf4292244); /* 49 */II(d, a, b, c, x[ 7], 10, 0x432aff97); /* 50 */II(c, d, a, b, x[14], 15, 0xab9423a7); /* 51 */II(b, c, d, a, x[ 5], 21, 0xfc93a039); /* 52 */II(a, b, c, d, x[12], 6, 0x655b59c3); /* 53 */II(d, a, b, c, x[ 3], 10, 0x8f0ccc92); /* 54 */II(c, d, a, b, x[10], 15, 0xffeff47d); /* 55 */II(b, c, d, a, x[ 1], 21, 0x85845dd1); /* 56 */II(a, b, c, d, x[ 8], 6, 0x6fa87e4f); /* 57 */II(d, a, b, c, x[15], 10, 0xfe2ce6e0); /* 58 */II(c, d, a, b, x[ 6], 15, 0xa3014314); /* 59 */II(b, c, d, a, x[13], 21, 0x4e0811a1); /* 60 */II(a, b, c, d, x[ 4], 6, 0xf7537e82); /* 61 */II(d, a, b, c, x[11], 10, 0xbd3af235); /* 62 */II(c, d, a, b, x[ 2], 15, 0x2ad7d2bb); /* 63 */II(b, c, d, a, x[ 9], 21, 0xeb86d391); /* 64 */state[0] += a;state[1] += b;state[2] += c;state[3] += d;
}int main(int argc, char *argv[])
{int i;unsigned char encrypt[] ="I am a student";unsigned char decrypt[16];MD5_CTX md5;MD5Init(&md5);MD5Update(&md5,encrypt,strlen((char *)encrypt));MD5Final(&md5,decrypt);printf("明文:%s\n密文:",encrypt);for(i=0;i<16;i++){printf("%02x",decrypt[i]);}printf("\n");return 0;
}

结果

2.DES算法

DES算法使用64位的密钥key将64位的明文输入块变为64位的密文输出块,并把输出块分为L0、R0两部分,每部分均为32位。其入口参数有三个:key、data、mode。key为加密解密使用的密钥,data为加密解密的数据,mode为其工作模式。当模式为加密模式时,明文按照64位进行分组,形成明文组,key用于对数据加密,当模式为解密模式时,key用于对数据解密。

代码

DES.cpp

#include <string.h>
#include <stdio.h>class DES
{public:~DES() {}void setkey(const unsigned char *);void enctransform(const unsigned char *,unsigned char *);void dectransform(const unsigned char *,unsigned char *);private:bool enckey[16][48];//存放加密子密钥// initial permutation IPconst static unsigned char IP_Table[64];// final permutation IP^-1const static unsigned char IPR_Table[64];// expansion operation matrixconst static unsigned char E_Table[48];// 32-bit permutation function P used on the output of the S-boxesconst static unsigned char P_Table[32];// permuted choice table (key)const static unsigned char PC1_Table[56];// permuted choice key (table)const static unsigned char PC2_Table[48];// number left rotations of pc1const static unsigned char LOOP_Table[16];// The S-boxesconst static unsigned char S_Box[8][4][16];//加入其他私有成员函数
};const unsigned char DES::IP_Table[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
};
// final permutation IP^-1
const unsigned char DES::IPR_Table[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
};
// expansion operation matrix
const unsigned char DES::E_Table[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
};
// 32-bit permutation function P used on the output of the S-boxes
const unsigned char DES::P_Table[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
};
// permuted choice table (key)
const unsigned char DES::PC1_Table[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
};
// permuted choice key (table)
const unsigned char DES::PC2_Table[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
};
// number left rotations of pc1
const unsigned char DES::LOOP_Table[16] = {1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1
};
// The S-boxes
const unsigned char DES::S_Box[8][4][16] = {// S114, 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,// S215, 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,// S310,  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,// S47, 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,// S52, 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,// S612,  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,// S74, 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,// S813,  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
};void DES::setkey( unsigned char const *userkey/*用户输入的64位密钥首地址*/ )
{//密钥扩展算法,即由主密钥生成子密钥unsigned char userkey2[8];for(int ii=0;ii<8;ii++)userkey2[ii]=userkey[ii];//复制主密钥//化比特为数组unsigned char key[64];for(int i=7;i>=0;i--)for(int j=7;j>=0;j--){key[i*8+j]=userkey2[i]&0x01;userkey2[i]=userkey2[i]>>1;}//去除校验位,变为56unsigned char key2[56];for(int k=1,kk=0;k<=64;k++){if(k%8!=0){key2[kk]=key[k-1];kk++;}}unsigned char c0[28];unsigned char c1[28];//拆分为两个for(int p=0;p<28;p++){c0[p]=key2[PC1_Table[p]-1];c1[p]=key2[PC1_Table[p+28]-1];//c1就是d}int tempint1;int tempint2;int tempint11;int tempint22;//16个子密钥的生成for(int i=0;i<16;i++){if(LOOP_Table[i]==1){tempint1=c0[0];tempint11=c1[0];for(int j=1;j<28;j++){c0[j-1]=c0[j];c1[j-1]=c1[j];}c0[27]=tempint1;c1[27]=tempint11;}else{tempint1=c0[0];tempint2=c0[1];tempint11=c1[0];tempint22=c1[1];for(int j=2;j<28;j++){c0[j-2]=c0[j];c1[j-2]=c1[j];}c0[26]=tempint1;c0[27]=tempint2;c1[26]=tempint11;c1[27]=tempint22;}for(int r=0;r<56;r++){if(r<28)key2[r]=c0[r];elsekey2[r]=c1[r-28];}for(int r=0;r<48;r++){enckey[i][r]=key2[PC2_Table[r]-1];}}
}void DES::enctransform( const unsigned char *In /*待加密的64位数据首地址*/,unsigned char *Out )
{//加密变换算法unsigned char In2[8];for(int ii=0;ii<8;ii++)In2[ii]=In[ii];//复制64位明文//化比特为数组unsigned char In3[64];for(int i=7;i>=0;i--)for(int j=7;j>=0;j--){In3[i*8+j]=In2[i]&0x01;In2[i]=In2[i]>>1;}unsigned char In4[64];for(int i=0;i<64; i++)In4[i]=In3[IP_Table[i]-1];//16次迭代unsigned char L[32],R[32],tempL[32],tempR[32],F[32],FP[32],ER[48];unsigned char B1[6],B2[6],B3[6],B4[6],B5[6],B6[6],B7[6],B8[6];for(int i=0;i<32;i++){L[i]=In4[i];R[i]=In4[i+32];}for(int i=0;i<16;i++){for(int j=0;j<32;j++){tempL[j]=L[j];tempR[j]=R[j];}for(int j=0;j<32;j++)L[j]=tempR[j];//f函数定义for(int i1=0;i1<48;i1++)ER[i1]=tempR[E_Table[i1]-1]^enckey[i][i1];for(int p=0;p<48;p++){int temp=p/6;switch(temp){case 0:  B1[p]=ER[p];break;case 1:  B2[p-6]=ER[p];break;case 2:  B3[p-12]=ER[p];break;case 3:  B4[p-18]=ER[p];break;case 4:  B5[p-24]=ER[p];break;case 5:  B6[p-30]=ER[p];break;case 6:  B7[p-36]=ER[p];break;case 7:  B8[p-42]=ER[p];break;default: printf("error in switch!\n");}}unsigned char f;f=S_Box[0][B1[0]*2+B1[5]][B1[1]*8+B1[2]*4+B1[3]*2+B1[4]];for(int f1=3;f1>=0;f1--){F[f1]=f&0x01;f=f>>1;}f=S_Box[1][B2[0]*2+B2[5]][B2[1]*8+B2[2]*4+B2[3]*2+B2[4]];for(int f1=3;f1>=0;f1--){F[f1+4]=f&0x01;f=f>>1;}f=S_Box[2][B3[0]*2+B3[5]][B3[1]*8+B3[2]*4+B3[3]*2+B3[4]];for(int f1=3;f1>=0;f1--){F[f1+8]=f&0x01;f=f>>1;}f=S_Box[3][B4[0]*2+B4[5]][B4[1]*8+B4[2]*4+B4[3]*2+B4[4]];for(int f1=3;f1>=0;f1--){F[f1+12]=f&0x01;f=f>>1;}f=S_Box[4][B5[0]*2+B5[5]][B5[1]*8+B5[2]*4+B5[3]*2+B5[4]];for(int f1=3;f1>=0;f1--){F[f1+16]=f&0x01;f=f>>1;}f=S_Box[5][B6[0]*2+B6[5]][B6[1]*8+B6[2]*4+B6[3]*2+B6[4]];for(int f1=3;f1>=0;f1--){F[f1+20]=f&0x01;f=f>>1;}f=S_Box[6][B7[0]*2+B7[5]][B7[1]*8+B7[2]*4+B7[3]*2+B7[4]];for(int f1=3;f1>=0;f1--){F[f1+24]=f&0x01;f=f>>1;}f=S_Box[7][B8[0]*2+B8[5]][B8[1]*8+B8[2]*4+B8[3]*2+B8[4]];for(int f1=3;f1>=0;f1--){F[f1+28]=f&0x01;f=f>>1;}for(int q=0;q<32;q++){FP[q]=F[P_Table[q]-1];}for(int k=0;k<32;k++){R[k]=tempL[k]^FP[k];}}//合并for(int i=0;i<32;i++){In4[i]=R[i];In4[i+32]=L[i];}//逆置换for(int i=0;i<64;i++){In3[i]=In4[IPR_Table[i]-1];}//转出  1 2 4 8 16 32 64 128for(int i=0;i<8;i++){Out[i]=0;for(int j=0;j<8;j++){int p=128,jj=j;while(jj!=0){p=p/2;jj--;}Out[i]+=In3[i*8+j]*p;}}
}int main()
{unsigned int buf[8];char buffer[17];unsigned char key[9], plaintext[9],ciphertext[9];DES mydes;int ii;printf("Please input key(length=16):\n****************\n");scanf("%s",buffer);sscanf(buffer,"%2x%2x%2x%2x%2x%2x%2x%2x",&buf[0],&buf[1],&buf[2],&buf[3],&buf[4],&buf[5],&buf[6],&buf[7]);for(ii=0;ii<8;ii++)key[ii]=buf[ii];printf("Please input plaintext(length=16):\n");scanf("%s",buffer);sscanf(buffer,"%2x%2x%2x%2x%2x%2x%2x%2x",&buf[0],&buf[1],&buf[2],&buf[3],&buf[4],&buf[5],&buf[6],&buf[7]);for(ii=0;ii<8;ii++)plaintext[ii]=buf[ii];mydes.setkey(key);mydes.enctransform(plaintext,ciphertext);for(ii=0;ii<8;ii++)buf[ii]=ciphertext[ii];printf("ciphertext:\n%02x%02x%02x%02x%02x%02x%02x%02x\n",buf[0],buf[1],buf[2],buf[3],buf[4],buf[5],buf[6],buf[7]);return 0;
}

结果

2种现代密码算法的设计与实现——C++相关推荐

  1. 信息安全密码学实验一:古典密码算法的设计与实现

    古典密码算法的设计与实现 1.仿射密码 加法密码和乘法密码结合就构成仿射密码,仿射密码的加密和解密算法是: C=Ek(m)=(k1m+k2)mod n D=(c-k2)mod n package cz ...

  2. TPM分析笔记(七)TPM 模块中的密码算法家族。

    目录 密码攻击 暴力破解 根据类型来计算算法强度 针对算法本身的攻击 安全的定义 密码家族 哈希(摘要) 哈希扩展(HashExtend) 基于哈希的消息认证码(HashedMessageAuthen ...

  3. 信息安全——维吉尼亚密码算法(C++实现)

    信息安全导论课程学习的实验一,维吉尼亚密码算法C++的实现. 维吉尼亚密码算法是一种代换密码算法,直观上来说,密钥一般短于明文长度,因此加密时需要将明文根据密钥长度进行分组,每一组明文根据密钥对应(0 ...

  4. 安全密码c语言编程,商用密码算法原理与C语言实现

    2020年1月1日,<中华人民共和国密码法>正式施行.国家鼓励和支持密码科学技术研究与应用,促进密码科学技术进步与创新,加强密码人才培养和队伍建设,采取多种形式加强密码安全教育.本书是在国 ...

  5. 信息安全复习三:古典密码之设计好的密码算法

    一.章节梗概 讨论以下算法,理解怎么设计好的密码算法的关键问题 1.Caesar cipher(替换密码) 2.单字母表密码(替换密码) 3.Playfair密码(多表代换密码) 4.维吉尼亚密码(多 ...

  6. 一种基于加密域的数字图像水印算法的设计与实现(附Matlab源码)

    一种基于加密域的数字图像水印算法的设计与实现 项目介绍 毕设项目 题目:一种基于加密域的数字图像水印算法的设计与实现 随着数字媒体技术的发展,数字媒体版权的保护得到了越来越多人的重视,数字水印技术作为 ...

  7. ROT13加密与解密(一种加密和解密都会得到同样答案的密文)“替换式密码算法”

    一. ROT13简介: ROT13(回转13位)是一种简易的替换式密码算法.它是一种在英文网络论坛用作隐藏八卦.妙句.谜题解答以及某些脏话的工具,目的是逃过版主或管理员的匆匆一瞥.ROT13 也是过去 ...

  8. aes子密钥生成c语言_一种基于流密码算法的子密钥生成方法与流程

    本发明涉及一种用于分组加解密算法的子密钥的生成方法. 背景技术: 随着信息技术的发展,信息安全性的问题却愈来愈显得突出,保证信息安全的一个重要技术就是密码学.密码学在信息安全技术中扮演着基础的角色,是 ...

  9. CTF-Crypto学习1(软件加壳、反汇编、Babe64、Rijndael密码算法)

    CTF-Crypto学习1(软件加壳.反汇编.Babe64.Rijndael密码算法) 1.软件加壳 定义: 加壳的全称应该是可执行程序资源压缩,压缩后的程序可以直接运行. 加壳的另一种常用的方式是在 ...

最新文章

  1. 《大数据分析原理与实践》——小结
  2. 如何在生产环境部署K2的流程
  3. 利用源代码包搭建LAMP
  4. java基础10(IO流)-字节流
  5. 饶过'(单引号)限制继续射入
  6. JAVA中基本类型Boolean占几个字节
  7. Codeblocks 中文乱码解决方法
  8. 关于宏定义的一些用法
  9. 大话数据结构PDF/word
  10. paypal快速支付流程图
  11. 带你Dart带你Diao之类(一)
  12. Java带宽限速器、Springboot限速器
  13. sed解析url的域名
  14. superview透明问题
  15. 永续合约短线交易技巧?
  16. 为自己的站点实现访客统计
  17. Vue源码流程图(函数名与源码对应)
  18. 有效的预防电脑辐射的方法
  19. 加拿大国家银行开展区块链试点,简化“复杂”谈判流程
  20. 超级庄家吕梁和中国股市第一案

热门文章

  1. Halcon基础知识——数组操作
  2. 配置你的 csh/tcsh
  3. pdf如何添加水印?
  4. a标签点击时如何弹出确认框?
  5. 公共rtsp_可用rtsp地址
  6. Windows 10中蓝牙鼠标连接
  7. PHP连接数据库学习手册
  8. 朋友圈问题(并查集)
  9. 图论 —— 弦图 —— MCS 算法
  10. Solidity合约中签名验证的一点实践