2种现代密码算法的设计与实现——C++
2种现代密码算法的设计与实现——C++
- 2种现代密码
- 1.MD5算法
- 代码
- 结果
- 2.DES算法
- 代码
- 结果
本文将介绍两种现代密码算法并进行代码实现:
- 使用 C++ 实现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位加在第一步结果的后面,这样信息长度就变为N512+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.仿射密码 加法密码和乘法密码结合就构成仿射密码,仿射密码的加密和解密算法是: C=Ek(m)=(k1m+k2)mod n D=(c-k2)mod n package cz ...
- TPM分析笔记(七)TPM 模块中的密码算法家族。
目录 密码攻击 暴力破解 根据类型来计算算法强度 针对算法本身的攻击 安全的定义 密码家族 哈希(摘要) 哈希扩展(HashExtend) 基于哈希的消息认证码(HashedMessageAuthen ...
- 信息安全——维吉尼亚密码算法(C++实现)
信息安全导论课程学习的实验一,维吉尼亚密码算法C++的实现. 维吉尼亚密码算法是一种代换密码算法,直观上来说,密钥一般短于明文长度,因此加密时需要将明文根据密钥长度进行分组,每一组明文根据密钥对应(0 ...
- 安全密码c语言编程,商用密码算法原理与C语言实现
2020年1月1日,<中华人民共和国密码法>正式施行.国家鼓励和支持密码科学技术研究与应用,促进密码科学技术进步与创新,加强密码人才培养和队伍建设,采取多种形式加强密码安全教育.本书是在国 ...
- 信息安全复习三:古典密码之设计好的密码算法
一.章节梗概 讨论以下算法,理解怎么设计好的密码算法的关键问题 1.Caesar cipher(替换密码) 2.单字母表密码(替换密码) 3.Playfair密码(多表代换密码) 4.维吉尼亚密码(多 ...
- 一种基于加密域的数字图像水印算法的设计与实现(附Matlab源码)
一种基于加密域的数字图像水印算法的设计与实现 项目介绍 毕设项目 题目:一种基于加密域的数字图像水印算法的设计与实现 随着数字媒体技术的发展,数字媒体版权的保护得到了越来越多人的重视,数字水印技术作为 ...
- ROT13加密与解密(一种加密和解密都会得到同样答案的密文)“替换式密码算法”
一. ROT13简介: ROT13(回转13位)是一种简易的替换式密码算法.它是一种在英文网络论坛用作隐藏八卦.妙句.谜题解答以及某些脏话的工具,目的是逃过版主或管理员的匆匆一瞥.ROT13 也是过去 ...
- aes子密钥生成c语言_一种基于流密码算法的子密钥生成方法与流程
本发明涉及一种用于分组加解密算法的子密钥的生成方法. 背景技术: 随着信息技术的发展,信息安全性的问题却愈来愈显得突出,保证信息安全的一个重要技术就是密码学.密码学在信息安全技术中扮演着基础的角色,是 ...
- CTF-Crypto学习1(软件加壳、反汇编、Babe64、Rijndael密码算法)
CTF-Crypto学习1(软件加壳.反汇编.Babe64.Rijndael密码算法) 1.软件加壳 定义: 加壳的全称应该是可执行程序资源压缩,压缩后的程序可以直接运行. 加壳的另一种常用的方式是在 ...
最新文章
- 《大数据分析原理与实践》——小结
- 如何在生产环境部署K2的流程
- 利用源代码包搭建LAMP
- java基础10(IO流)-字节流
- 饶过'(单引号)限制继续射入
- JAVA中基本类型Boolean占几个字节
- Codeblocks 中文乱码解决方法
- 关于宏定义的一些用法
- 大话数据结构PDF/word
- paypal快速支付流程图
- 带你Dart带你Diao之类(一)
- Java带宽限速器、Springboot限速器
- sed解析url的域名
- superview透明问题
- 永续合约短线交易技巧?
- 为自己的站点实现访客统计
- Vue源码流程图(函数名与源码对应)
- 有效的预防电脑辐射的方法
- 加拿大国家银行开展区块链试点,简化“复杂”谈判流程
- 超级庄家吕梁和中国股市第一案