大结局---Miracl库下完全实现SM2加密算法

 本次博文以前面的两次文章的函数定义、说明为基础进行扩展。

  并且参考了一些其他的优秀博客文章,比如KDF局部密钥派生函数的使用、十六进制字符串与二进制字符串以及普通字符串转换函数(自己也编写了一部分函数)、SM3杂凑签名算法(太懒了,完全拿来用了,取其精华,感谢博客主人)。

  完成本次实验前,进一步了解了C语言,这种直接面对内存进行操作的语言真的既让人爱又让人恨……

  然后,介绍一下我实现本算法的大概思路:从文件读入等待加密的明文,然后以二进制字符串形式(字符数组,定义了很多中间变量,做好准备吧)构造密文,中间还涉及十六进制形式的字符串,因为我需要把字符串转成16进制再转成二进制,并且中间有很多操作也和十六进制形式有关。

   最后,强调一下定义的这些函数都是对字符数组进行,然后把结果填充到另一个指定地址去,这种思想伴随了整个程序中……


 sm3头文件代码(参考与网址 https://blog.csdn.net/a344288106/ article/details/80094878 ):

  1 #include <stdio.h>
  2 #include <memory.h>
  3 #ifndef _SM3_H_
  4 #define _SM3_H_
  5  
  6 /*
  7 * SM3算法产生的哈希值大小(单位:字节)
  8 */
  9 #define SM3_HASH_SIZE 32 
 10  
 11 /*
 12 * SM3上下文
 13 */
 14 typedef struct SM3Context
 15 {
 16     unsigned int intermediateHash[SM3_HASH_SIZE / 4];
 17     unsigned char messageBlock[64];
 18 } SM3Context;
 19  
 20 /*
 21 * SM3计算函数
 22 */
 23 unsigned char *SM3Calc(const unsigned char *message,unsigned int messageLen, unsigned char digest[SM3_HASH_SIZE]);
 24  
 25 #endif // _SM3_H_
 26 /*
 27 * 判断运行环境是否为小端
 28 */
 29 static const int endianTest = 1;
 30 #define IsLittleEndian() (*(char *)&endianTest == 1)
 31  
 32 /*
 33 * 向左循环移位
 34 */
 35 #define LeftRotate(word, bits) ( (word) << (bits) | (word) >> (32 - (bits)) )
 36  
 37 /*
 38 * 反转四字节整型字节序
 39 */
 40 unsigned int *ReverseWord(unsigned int *word)
 41 {
 42     unsigned char *byte, temp;
 43  
 44     byte = (unsigned char *)word;
 45     temp = byte[0];
 46     byte[0] = byte[3];
 47     byte[3] = temp;
 48  
 49     temp = byte[1];
 50     byte[1] = byte[2];
 51     byte[2] = temp;
 52     return word;
 53 }
 54  
 55 /*
 56 * T
 57 */
 58 unsigned int T(int i)
 59 {
 60     if (i >= 0 && i <= 15)
 61         return 0x79CC4519;
 62     else if (i >= 16 && i <= 63)
 63         return 0x7A879D8A;
 64     else
 65         return 0;
 66 }
 67  
 68 /*
 69 * FF
 70 */
 71 unsigned int FF(unsigned int X, unsigned int Y, unsigned int Z, int i)
 72 {
 73     if (i >= 0 && i <= 15)
 74         return X ^ Y ^ Z;
 75     else if (i >= 16 && i <= 63)
 76         return (X & Y) | (X & Z) | (Y & Z);
 77     else
 78         return 0;
 79 }
 80  
 81 /*
 82 * GG
 83 */
 84 unsigned int GG(unsigned int X, unsigned int Y, unsigned int Z, int i)
 85 {
 86     if (i >= 0 && i <= 15)
 87         return X ^ Y ^ Z;
 88     else if (i >= 16 && i <= 63)
 89         return (X & Y) | (~X & Z);
 90     else
 91         return 0;
 92 }
 93  
 94 /*
 95 * P0
 96 */
 97 unsigned int P0(unsigned int X)
 98 {
 99     return X ^ LeftRotate(X, 9) ^ LeftRotate(X, 17);
100 }
101  
102 /*
103 * P1
104 */
105 unsigned int P1(unsigned int X)
106 {
107     return X ^ LeftRotate(X, 15) ^ LeftRotate(X, 23);
108 }
109  
110 /*
111 * 初始化函数
112 */
113 void SM3Init(SM3Context *context)
114 {
115     context->intermediateHash[0] = 0x7380166F;
116     context->intermediateHash[1] = 0x4914B2B9;
117     context->intermediateHash[2] = 0x172442D7;
118     context->intermediateHash[3] = 0xDA8A0600;
119     context->intermediateHash[4] = 0xA96F30BC;
120     context->intermediateHash[5] = 0x163138AA;
121     context->intermediateHash[6] = 0xE38DEE4D;
122     context->intermediateHash[7] = 0xB0FB0E4E;
123 }
124  
125 /*
126 * 处理消息块
127 */
128 void SM3ProcessMessageBlock(SM3Context *context)
129 {
130     int i;
131     unsigned int W[68];
132     unsigned int W_[64];
133     unsigned int A, B, C, D, E, F, G, H, SS1, SS2, TT1, TT2;
134  
135     /* 消息扩展 */
136     //printf("扩展后的消息 W0-W67:\n");
137     for (i = 0; i < 16; i++)
138     {
139         W[i] = *(unsigned int *)(context->messageBlock + i * 4);
140         if (IsLittleEndian())
141             ReverseWord(W + i);
142         //if((i % 8) == 0) printf("%02d: ",i);
143         //printf("  %08x",W[i]);
144         //if(((i+1) % 8) == 0) printf("\n");
145     }
146     for (i = 16; i < 68; i++)
147     {
148         W[i] = P1(W[i - 16] ^ W[i - 9] ^ LeftRotate(W[i - 3], 15))
149             ^ LeftRotate(W[i - 13], 7)
150             ^ W[i - 6];
151         //if((i % 8) == 0) printf("%02d: ",i);
152         //printf("  %08x", W[i]);  
153          //if(((i+1) % 8) == 0) printf("\n");  
154     }
155     //printf("\n扩展后的消息 W'0-W'63:\n");
156     for (i = 0; i < 64; i++)
157     {
158         W_[i] = W[i] ^ W[i + 4];
159         //if((i % 8) == 0) printf("%02d: ",i);
160         //printf("  %08x",W_[i]);
161         //if(((i+1) % 8) == 0) printf("\n");  
162     }
163  
164     /* 消息压缩 */
165     A = context->intermediateHash[0];
166     B = context->intermediateHash[1];
167     C = context->intermediateHash[2];
168     D = context->intermediateHash[3];
169     E = context->intermediateHash[4];
170     F = context->intermediateHash[5];
171     G = context->intermediateHash[6];
172     H = context->intermediateHash[7];
173     //printf("迭代压缩中间值:\n");
174     //printf("i     A       B        C         D         E        F        G       H\n");
175     //printf("   %08x %08x %08x %08x %08x %08x %08x %08x\n",A,B,C,D,E,F,G,H);
176     for (i = 0; i < 64; i++)
177     {
178         SS1 = LeftRotate((LeftRotate(A, 12) + E + LeftRotate(T(i), i)), 7);
179         SS2 = SS1 ^ LeftRotate(A, 12);
180         TT1 = FF(A, B, C, i) + D + SS2 + W_[i];
181         TT2 = GG(E, F, G, i) + H + SS1 + W[i];
182         D = C;
183         C = LeftRotate(B, 9);
184         B = A;
185         A = TT1;
186         H = G;
187         G = LeftRotate(F, 19);
188         F = E;
189         E = P0(TT2);
190         //printf("%02d %08x %08x %08x %08x %08x %08x %08x %08x\n",i,A,B,C,D,E,F,G,H);
191     }
192     context->intermediateHash[0] ^= A;
193     context->intermediateHash[1] ^= B;
194     context->intermediateHash[2] ^= C;
195     context->intermediateHash[3] ^= D;
196     context->intermediateHash[4] ^= E;
197     context->intermediateHash[5] ^= F;
198     context->intermediateHash[6] ^= G;
199     context->intermediateHash[7] ^= H;
200 }
201  
202 /*
203 * SM3算法主函数
204 */
205 unsigned char *SM3Calc(const unsigned char *message,unsigned int messageLen, unsigned char digest[SM3_HASH_SIZE])
206 {
207 
208     SM3Context context;
209     unsigned int i, remainder, bitLen;
210     /* 初始化上下文 */
211     SM3Init(&context);
212  
213     /* 对前面的消息分组进行处理 */
214     for (i = 0; i < messageLen / 64; i++)  //i是Bi分组数目(512bits),只有一组则不处理,因为0< 0不成立
215     {
216         memcpy(context.messageBlock, message + i * 64, 64);
217         SM3ProcessMessageBlock(&context);
218     }
219  
220     /* 填充消息分组,并处理 */
221     bitLen = messageLen * 8;  //消息的比特长度,用于待会的填充
222     if (IsLittleEndian())
223         ReverseWord(&bitLen);
224     remainder = messageLen % 64;
225     memcpy(context.messageBlock, message + i * 64, remainder);
226     context.messageBlock[remainder] = 0x80;
227     if (remainder <= 55)
228     {
229         memset(context.messageBlock + remainder + 1, 0, 64 - remainder - 1 - 8 + 4);
230         memcpy(context.messageBlock + 64 - 4, &bitLen, 4); //最后四字节存放信息长度
231         SM3ProcessMessageBlock(&context);
232     }
233     else
234     {
235         memset(context.messageBlock + remainder + 1, 0, 64 - remainder - 1);//本组余下的全填零
236         SM3ProcessMessageBlock(&context);
237         memset(context.messageBlock, 0, 64 - 4);
238         memcpy(context.messageBlock + 64 - 4, &bitLen, 4);
239         SM3ProcessMessageBlock(&context);
240     }
241  
242     /* 返回结果 */
243     if (IsLittleEndian())
244         for (i = 0; i < 8; i++)
245             ReverseWord(context.intermediateHash + i);
246     memcpy(digest,context.intermediateHash, SM3_HASH_SIZE);
247  
248     return digest;
249 }


下面是KDF函数定义(参考与网址https://blog.csdn.net/heidlyn/article/details/53993002 )

 1 int KDF(const char* cdata, int datalen, int keybitlen, char* retdata)
 2 {
 3     int nRet = -1;
 4     char* hexstring[512]={0};
 5     char* bytestring[256]={0};
 6     unsigned char *pRet;
 7     unsigned char *pData;
 8     unsigned char cdgst[32]={0};
 9     unsigned char cCnt[4] = {0};
10     int nCnt  = 1;
11     int nDgst = 32; 
12     int keybytelen=keybitlen/8; //keybytelen是明文(未来密钥)的字节长度
13     int nTimes = (keybytelen+31)/32;
14     int i=0;
15     if(cdata==NULL || datalen<=0 || keybitlen<=0)
16         goto err;
17     if(NULL == (pRet=(unsigned char *)malloc(keybytelen)))
18         goto err;
19     if(NULL == (pData=(unsigned char *)malloc(datalen+4)))
20         goto err;
21     memset(pRet,  0, keybytelen);
22     memset(pData, 0, datalen+4);
23     memcpy(pData, cdata, datalen);
24     for(; i<nTimes; i++)
25     {
26         cCnt[0] =  (nCnt>>24) & 0xFF;
27         cCnt[1] =  (nCnt>>16) & 0xFF;
28         cCnt[2] =  (nCnt>> 8) & 0xFF;
29         cCnt[3] =  (nCnt    ) & 0xFF;
30         memcpy(pData+datalen, cCnt, 4);
31         Bin2Hex(pData,hexstring,datalen+4);//二进制字符串长度为datalen+4
32         Hex2Byte(hexstring,bytestring,datalen/4+1);//十六进制字符串长度为1/4(datalen+4)
33         SM3Calc(bytestring,(datalen+4)/8,cdgst); //字符串长度为1/8(datalen+4);应该传入字符串bytestring,而非比特串
34         if(i == nTimes-1) //最后一次计算,根据keybytelen/32是否整除,截取摘要的值
35             if(keybytelen%32 != 0)
36                 nDgst = keybytelen%32;  
37         memcpy(pRet+32*i, cdgst, nDgst);
38         nCnt ++;  //计数器
39     }
40     bzero(hexstring,sizeof(hexstring));
41     Str2Hex(pRet,hexstring,keybytelen);
42     Hex2Bin(hexstring,retdata,strlen(hexstring));
43     nRet = 0;
44 err:
45     if(pRet)
46         free(pRet);
47     if(pData)
48         free(pData);
49 
50     return nRet;
51 }


 好的,下面就是SM2主函数加解密代码:

  1 int main(){  //前面定义很多变量,不再一一介绍,后面用到再提
  2     big a,b,p,Gx,Gy,n,db,k;
  3     big x1,y1,x2,y2;
  4     int kbitlen;
  5     char plain[1024]={0}; //存放文件中读取的明文字符串
  6     char plain_bin[8192]={0}; //存放明文的二进制字符串
  7     char C2_bin[8192]={0};    //存放解密出明文的二进制字符串
  8     char sm3_dgst[33]={0};  //存放 sm3 32字节的杂凑摘要
  9     char crypt[3072]={0};   //存放加密生成的密文的二进制形式
 10     char Hexstring1[65]={0};    
 11     char Hexstring2[65]={0};
 12     char Hexstring3[2048]={0};    
 13     char HexTemp[2048]={0};
 14     char t1[8192]={0};    
 15     char Binarystring1[257]={0};
 16     char Binarystring2[257]={0};    
 17     char Binarystring3[513]={0};
 18     FILE *fp; //存放的文件存放推荐的参数a、b、p、Gx、Gy、n等等
 19     FILE *input_string;//存放明文
 20     epoint* G=NULL;  //基点G
 21     epoint* Pb=NULL; //公钥点Pb
 22     epoint* T1=NULL; //点T1(x1,y1)=[k]G
 23     epoint* T2=NULL;    
 24     epoint* D1=NULL;
 25     epoint* D2=NULL;
 26     miracl* mip=mirsys(1000,16);//初始化大数库
 27     a=mirvar(0);    
 28     b=mirvar(0); 
 29     p=mirvar(0); //p 256 bits
 30     Gx=mirvar(0);    
 31     Gy=mirvar(0);    
 32     n=mirvar(0);
 33     k=mirvar(0);    
 34     db=mirvar(0);//用户私钥数字
 35     x1=mirvar(0);    
 36     y1=mirvar(0);    
 37     x2=mirvar(0);    
 38     y2=mirvar(0);
 39     fp=fopen("abp.txt","r+");  //fp指向同目录下存放参数的文件
 40     if(fp==0)
 41     {
 42         printf("文件打开失败!");
 43         exit(1);
 44     }
 45     mip->IOBASE=16;//下面依次读取十六进制的参数
 46     cinnum(a,fp);    
 47     cinnum(b,fp);    
 48     cinnum(p,fp);    
 49     cinnum(Gx,fp);
 50     cinnum(Gy,fp);
 51     cinnum(n,fp);    
 52     fclose(fp);//关闭参数文件指针
 53     system("color E");
 54     printf("---------参数生成---------\n");  //打印已知参数
 55     printf("参数a=");    
 56     cotnum(a,stdout);
 57     printf("参数b=");    
 58     cotnum(b,stdout);
 59     printf("有限域素数p=");    
 60     cotnum(p,stdout);
 61     printf("基点横坐标Gx=");
 62     cotnum(Gx,stdout);
 63     printf("基点纵坐标Gy=");
 64     cotnum(Gy,stdout);
 65     printf("基点的阶n=");    
 66     cotnum(n,stdout); 
 67     bigrand(n,db);           //db<n-1,随机生成私钥,然后打印
 68     printf("选取私钥数字db=");    
 69     cotnum(db,stdout);
 70     ecurve_init(a,b,p,MR_PROJECTIVE);//定义、初始化曲线方程
 71     G=epoint_init();    
 72     Pb=epoint_init();//初始化重要的点
 73     T1=epoint_init();    
 74     T2=epoint_init();
 75     if(epoint_set(Gx,Gy,0,G))  //验证、生成基点 G
 76         printf("基点G生成成功\n");
 77     else{
 78         printf("基点G生成失败!\n"); return 1;
 79     }
 80     ecurve_mult(db,G,Pb);   //Pb=db * G ,倍点运算----点的乘法函数
 81     printf("公钥点Pb生成成功!\n");
 82     printf("--------------加密过程---------------\n");
 83     bigrand(n,k);  //k<n 随机生成k,然后打印
 84     printf("选取随机数k=");    
 85     cotnum(k,stdout);
 86     ecurve_mult(k,G,T1);  //生成点T1坐标(x1,y1)=[k]G
 87     printf("点T1生成成功!\n");
 88     epoint_get(T1,x1,y1);//获取点x1、y1坐标
 89     cotstr(x1,Hexstring1);//x1存入十六进制字符串数组
 90     cotstr(y1,Hexstring2);//y1存入十六进制字符串数组
 91     //用函数把十六进制转成二进制
 92     Hex2Bin(Hexstring1,Binarystring1,strlen(Hexstring1));
 93     Hex2Bin(Hexstring2,Binarystring2,strlen(Hexstring2));
 94     //把C1 即x1|y1填入密文二进制数组最开始的部分
 95     sprintf(crypt,"%s%s",Binarystring1,Binarystring2);     
 96     printf("\n目前的密文长度为:%d,内容:\n",strlen(crypt));
 97     puts(crypt); 
 98     bzero(Hexstring1,sizeof(Hexstring1));//清空一下用过的中间数组
 99     bzero(Hexstring2,sizeof(Hexstring2));
100     bzero(Binarystring1,sizeof(Binarystring1));
101     bzero(Binarystring2,sizeof(Binarystring2));
102     input_string=fopen("input.txt","r+");//从文件读取明文字符串
103     fgets(plain,sizeof(plain),input_string);
104     fclose(input_string);
105     //printf("请输入明文字符串:");//可以自己输入
106     //gets(plain);
107     kbitlen=strlen(plain)*8; //明文bit长度
108     printf("输入明文是%s,明文比特长度为%d.\n",plain,kbitlen);
109     //将明文以二进制形式填充进plain_bin字符串内
110     Str2Hex(plain,Hexstring3,strlen(plain)); 
111     //Hexstring3只是一个中间媒介,存放明文16进制信息,后面用得到!!!
112     Hex2Bin(Hexstring3,plain_bin,strlen(Hexstring3));
113     ecurve_mult(k,Pb,T2); //T2坐标(x2,y2)=[k]Pb
114     printf("点T2生成成功!\n");
115     epoint_get(T2,x2,y2); 
116     cotstr(x2,Hexstring1);
117     cotstr(y2,Hexstring2);
118     //HexTemp存放十六进制形式的 x2|M|y2
119     sprintf(HexTemp,"%s%s%s",Hexstring1,Hexstring3,Hexstring2);
120     Hex2Bin(Hexstring1,Binarystring1,strlen(Hexstring1));
121     Hex2Bin(Hexstring2,Binarystring2,strlen(Hexstring2));
122     //Binarystring3目前存放x2|y2,用于后面的KDF计算
123     sprintf(Binarystring3,"%s%s",Binarystring1,Binarystring2);    
124     bzero(Hexstring1,sizeof(Hexstring1));  //清空一波
125     bzero(Hexstring2,sizeof(Hexstring2));
126     bzero(Hexstring3,sizeof(Hexstring3));
127     bzero(Binarystring1,sizeof(Binarystring1));
128     bzero(Binarystring2,sizeof(Binarystring2));
129     //返回结果t1存放kbitlen长度的密钥
130     KDF(Binarystring3,512,kbitlen,t1);        
131     if(strlen(plain_bin)==strlen(t1))
132         printf("长度一致,可以进行异或!\n");
133     //把C2 = t1^M 填充到最后的密文中,如果成功返回值应该是0
134     if(Bin_XOR(plain_bin,t1,crypt+strlen(crypt))!=0) 
135         printf("异或出错!");
136     printf("\n目前的密文长度为:%d,内容:\n",strlen(crypt));
137     puts(crypt); 
138     bzero(t1,sizeof(t1));
139     bzero(plain,sizeof(plain));//销毁明文字符串数组,保证解密准确性
140     //暂时拿plain存放byte形式的C2:x2|M|y2
141     Hex2Byte(HexTemp,plain,strlen(HexTemp));    
142     bzero(HexTemp,sizeof(HexTemp));
143     //计算sm3哈希值C3 = Hash(x2 ∥ M ∥ y2),存放到sm3_dgst byte类型
144     SM3Calc(plain,strlen(plain),sm3_dgst);
145     Str2Hex(sm3_dgst,Hexstring1,strlen(sm3_dgst));
146     //哈希结果转二进制类型,写入密文crypt的中间部分
147     Hex2Bin(Hexstring1,crypt+strlen(crypt),strlen(Hexstring1));
148     bzero(Hexstring1,sizeof(Hexstring1));
149     printf("\n目前的密文长度为:%d,至此,加密成功!密文内容:\n",strlen(crypt));
150     puts(crypt);  
151     //后续处理,清空一切不需要的数组,只保留必要的信息
152     bzero(plain,sizeof(plain));    bzero(plain_bin,sizeof(plain_bin));
153     bzero(sm3_dgst,sizeof(sm3_dgst));
154     epoint_free(T1);    
155     epoint_free(T2);//释放epoint类型点坐标
156     x1=mirvar(0);
157     y1=mirvar(0);//坐标值清零,后面还会用到
158     x2=mirvar(0);    
159     y2=mirvar(0);
160     printf("------------解密过程--------------\n");
161     printf("现在知道的信息有:收到的密文crypt\n C1部分长度为512bits,分别存储x1、y1的坐标信息\n kbitlen:代表明文的比特长度,对应密文C2部分的长度\n 解密者自己的私钥db\n");
162     strncpy(Binarystring1,crypt,256);        // x1二进制
163     strncpy(Binarystring2,crypt+256,256);  // y1二进制
164     Bin2Hex(Binarystring1,Hexstring1,256); // x1十六进制
165     Bin2Hex(Binarystring2,Hexstring2,256); // y1十六进制
166     mip->IOBASE=16;
167     cinstr(x1,Hexstring1);
168     cinstr(y1,Hexstring2);
169     bzero(Binarystring1,sizeof(Binarystring1));
170     bzero(Binarystring2,sizeof(Binarystring2));
171     bzero(Hexstring1,sizeof(Hexstring1));
172     bzero(Hexstring2,sizeof(Hexstring2));
173     D1=epoint_init(); //初始化解密过程中将要用到的点
174     D2=epoint_init();
175     if(epoint_set(x1,y1,0,D1))
176             printf("点D1生成成功\n");
177     else{
178         printf("点D1生成失败!\n");
179         return 0;
180     }
181     ecurve_mult(db,D1,D2); //点乘得到D2,解密非常关键的一步!!!
182     epoint_get(D2,x2,y2); //获取D2坐标信息一直转到二进制类型
183     cotstr(x2,Hexstring1);    cotstr(y2,Hexstring2);
184     Hex2Bin(Hexstring1,Binarystring1,strlen(Hexstring1));
185     Hex2Bin(Hexstring2,Binarystring2,strlen(Hexstring2));
186     sprintf(Binarystring3,"%s%s",Binarystring1,Binarystring2);//Binarystring3目前存放x2|y2
187     bzero(Hexstring3,sizeof(Hexstring3));
188     bzero(Binarystring1,sizeof(Binarystring1));
189     bzero(Binarystring2,sizeof(Binarystring2));
190     //计算t1=KDF(x2' ∥ y2', klen)
191     KDF(Binarystring3,512,kbitlen,t1);      
192     bzero(Binarystring3,sizeof(Binarystring3));
193     //从C中取出比特串C2bin,计算M ′ = C2 ⊕ t'
194     strncpy(C2_bin,crypt+512,kbitlen);     
195     Bin_XOR(t1,C2_bin,plain_bin);    // M'是 二进制 plain_bin
196     //M'是 十六进制 Hexstring3
197     Bin2Hex(plain_bin,Hexstring3,strlen(plain_bin));
198     //HexTemp 存放hex形式的 x2|M'|y2
199     sprintf(HexTemp,"%s%s%s",Hexstring1,Hexstring3,Hexstring2);
200     bzero(Hexstring1,sizeof(Hexstring1));
201     bzero(Hexstring2,sizeof(Hexstring2));
202     // 拿plain存放字符串形式的C2:x2|M'|y2
203     Hex2Byte(HexTemp,plain,strlen(HexTemp));
204     // u = Hash(x2 ∥ M '∥ y2) 还是存在变量sm3_dgst内
205     SM3Calc(plain,strlen(plain),sm3_dgst);
206     // u转成16进制hash值
207     Str2Hex(sm3_dgst,Hexstring1,strlen(sm3_dgst));
208     // u转成二进制 256 bits hash值
209     Hex2Bin(Hexstring1,Binarystring1,strlen(Hexstring1));
210     //从密文里面提取出最后的一部分信息赋给Binarystring2
211     strncpy(Binarystring2,crypt+512+kbitlen,256);    
212     if(strcmp(Binarystring1,Binarystring2)==0){  //匹配
213         printf("*********************匹配成功!!!!**********************\n");
214         bzero(plain,sizeof(plain));
215         Hex2Byte(Hexstring3,plain,strlen(Hexstring3));
216         printf("解密得到:\n");
217         puts(plain);
218     }
219     bzero(Hexstring3,sizeof(Hexstring3));
220     bzero(Hexstring1,sizeof(Hexstring1));
221     bzero(plain,sizeof(plain));
222     bzero(Binarystring1,sizeof(Binarystring1));
223     printf("----------------------------结束----------------------------\n");  //后续处理
224     mirkill(a);    
225     mirkill(b);    
226     mirkill(p);
227     mirkill(n);
228     mirkill(Gx);
229     mirkill(Gy);
230     mirkill(db);
231     mirkill(k);
232     mirkill(x1);    
233     mirkill(x2);    
234     mirkill(y1);
235     mirkill(y2);
236     epoint_free(G);    
237     epoint_free(Pb);    
238     epoint_free(D1);    
239     epoint_free(D2);
240     mirexit();
241     return 0;
242 }

abp.txt内使用国密推荐参数以及提供的一段明文:

扫描二维码关注公众号,回复: 4817042 查看本文章


执行效果:

(图不完整,右边还有很长的数据……)

解密成功!

猜你喜欢

转载自www.cnblogs.com/Higgerw/p/10225943.html