大結局---Miracl庫下完全實現SM2加密演算法
阿新 • • 發佈:2019-01-07
本次博文以前面的兩次文章的函式定義、說明為基礎進行擴充套件。
並且參考了一些其他的優秀部落格文章,比如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 intmessageLen, 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內使用國密推薦引數以及提供的一段明文:
執行效果:
(圖不完整,右邊還有很長的資料……)
解密成功!