DES算法C语言实现
生活随笔
收集整理的這篇文章主要介紹了
DES算法C语言实现
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
有關(guān)DES的加密流程詳解des算法加密流程_lkw23333的博客-CSDN博客_des密鑰加密過程
此處只做簡略介紹,或者看代碼注釋
簡要流程
(1)輸入8位字符明文以及設(shè)定8位字符的加密密鑰;
(2)將字符串的明文轉(zhuǎn)換為64位的二進制表示;密鑰也轉(zhuǎn)換為64位二進制表示;
(3)對64位的密鑰進行密鑰擴展生16個48位的子密鑰;
(4)對64位明文進行ip置換,分成L與R兩組各32位;
(5)R經(jīng)過輪函數(shù)F后與L進行異或操作生成新的R,新的L由之前的R代替;
(6)重復(fù)上述步驟16次后再進行一次IP逆置換即可得到64位密文;
(7)將加密后64位密文轉(zhuǎn)為16位16進制輸出方便顯示;
(8)解密與加密步驟相同只是部分操作相反;
總結(jié)
整個des算法涉及到的那種晦澀的理論知識并不多所以理解起來很容易。各種操作通過代碼實現(xiàn)起來都很ez,理解起來也很ez。就是過程稍微有點繁雜,而且在寫代碼的過程中不能調(diào)試,只能寫完了調(diào),這就導(dǎo)致找bug有點痛苦。不過這個過程是有收獲的。
#include<stdio.h> #include<string.h>int 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 }; // IP-1置換表 int 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 };// E擴展表 int 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 }; // PC1置換表 int 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 };// pc2表 int 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 }; // 移位表 int LOOP_Table[16]={1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 };// S盒 int 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, 0, 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, 0, 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 };//P置換表 int 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 };//執(zhí)行des加密 void doDes(int *mingBit, char *ciphertext, int *keyBit); //拷貝數(shù)組 void bitCopy(int *input, int *output, int length); //做ip置換和逆置換 void doIp(int *array, int length, int *table); //異或運算 void doXor(int *output, int *input, int length); //E盒擴展 void doE(int *R, int *eTemp, int length); //S盒壓縮 void doS(int *R, int *eTemp); //P盒置換 void doP(int *array); //兩個PC表的置換 void doPc_1(int *keyBit, int *output); void doPc_2(int *iKey, int *C, int *D); //循環(huán)左移動 void lMove(int *C, int *D, int moveBit); //子密鑰生成 void setIkey(int *keyBit, int iKey[16][48]); //輪函數(shù)F void lunF(int *R, int *iKey); //字符轉(zhuǎn)位 void charToBit(char *input , int *output, int length); //位轉(zhuǎn)字符 void bitToChar(int *input, char *output, int length); //des解密函數(shù) void deDes(char *mingWen,char *ciphertext, char *keyBit);//ip置換根據(jù)table確定 void doIp(int *array, int length, int *table){int temp[64] = {0};bitCopy(array, temp, 64);for(int i = 0; i < length; ++i){array[i] = temp[table[i] - 1];} }//整個程序的異或運算執(zhí)行函數(shù) void doXor(int *output, int *input, int length){for(int i=0; i<length; ++i){output[i] = output[i] ^ input[i];} }//E盒擴展 32——>48,方便后面與子密鑰異或 void doE(int *R, int *eTemp, int length) {for(int i = 0; i < length; ++i){eTemp[i] = R[E_Table[i] - 1];} }//S盒壓縮 48——>32 void doS(int *R, int *eTemp) {int i, x, y;//注意指針的移動步數(shù)for(i = 0; i < 8; ++i, eTemp += 6, R += 4){x = eTemp[0]*2 + eTemp[5];y = eTemp[1]*8 + eTemp[2]*4 + eTemp[3]*2 + eTemp[4];// printf("%d %d\n", x, y);char T = (char)S_Box[i][x][y];charToBit(&T, R, 4);}} //簡單的P盒置換 void doP(int *array) {int temp[32] = {0};bitCopy(array, temp, 32);for(int i = 0; i < 32; ++i){array[i] = temp[P_Table[i] - 1];} } //密鑰的pc_1表置換,剔除奇偶校驗位 void doPc_1(int *keyBit, int *output){for(int i = 0; i < 56; ++i){output[i] = keyBit[PC1_Table[i] - 1];} }//合并c,d兩部分進行pc_2的置換 56——>48 void doPc_2(int *iKey, int *C, int *D){int temp[56]={0};bitCopy(C, temp, 28);bitCopy(D, temp+28, 28);for(int i=0; i<48; ++i){iKey[i] = temp[PC2_Table[i]-1];} }//密鑰循環(huán)左移 void lMove(int *C, int *D, int moveBit){int temp[28] = {0};bitCopy(C, temp, 28);bitCopy(temp+moveBit, C, 28-moveBit);bitCopy(temp, C+28-moveBit, moveBit);bitCopy(D, temp, 28);bitCopy(temp+moveBit, D, 28-moveBit);bitCopy(temp, D+28-moveBit, moveBit);}//生成子密鑰 void setIkey(int *keyBit, int iKey[16][48]) {int temp[56]={0};int C[28];int D[28];doPc_1(keyBit, temp);//先做pc1剔除校驗位,在拆成兩組bitCopy(temp, C, 28);bitCopy(temp+28, D, 28);for(int i=0; i<16; ++i){lMove(C, D, LOOP_Table[i]);doPc_2(iKey[i], C, D);} }void lunF(int *R, int *iKey) {int eTemp[48]={0};//E盒擴展doE(R, eTemp, 48);//和密鑰異或doXor(eTemp, iKey, 48);//S盒壓縮doS(R, eTemp);//P盒壓縮doP(R);}//字符轉(zhuǎn)換為位方便加密 void charToBit(char *input , int *output, int length) {int i=0;for(i=0;i < length;i++){output[i]=(input[i/8]>>(i%8))&1;}} //位轉(zhuǎn)字符,復(fù)原 void bitToChar(int *input, char *output, int length) {int i;for(i=0;i<(length/8);i++){output[i]=0;}for(i=0;i<length;i++){output[i/8]|= input[i]<<(i%8);}}//整個程序,拷貝用的函數(shù) void bitCopy(int *input, int *output, int length) {int i;for(i = 0; i < length; ++i){output[i] = input[i];} }//執(zhí)行DES void doDes(int *mingBit, char *ciphertext, int *keyBit){int *L = &mingBit[0];int *R = &mingBit[32];int temp[32] = {0};//借助temp實現(xiàn)L,R的賦值int iKey[16][48] = {0};//ip置換doIp(mingBit, 64, IP_Table);//生成子密鑰setIkey(keyBit, iKey);//16輪跑起來for(int i=0; i<16; ++i){bitCopy(R, temp, 32);//執(zhí)行F函數(shù)lunF(R, iKey[i]);//與L異或doXor(L, R, 32);bitCopy(L, R, 32);bitCopy(temp, L, 32);}//IP逆置換doIp(mingBit, 64, IPR_Table);//將密文轉(zhuǎn)成16進制顯示bitToHex(ciphertext, mingBit, 64); } //解密函數(shù),與des差不多 void deDes(char *mingWen,char *ciphertext, char *keyBit)// DES輪解密算法; {int cBit[64]={0};int *L=&cBit[0];int *R=&cBit[32];int temp[32]={0};int iKey[16][48] = {0};hexToBit(cBit, ciphertext, 64);doIp(cBit, 64, IP_Table);setIkey(keyBit, iKey);//密鑰從后往前,L,R與DES相反for(int i=15;i>=0;i--){bitCopy(L, temp, 32);lunF(L, iKey[i]);doXor(R, L, 32);bitCopy(R, L, 32);bitCopy(temp, R, 32);}doIp(cBit, 64, IPR_Table);printf("\n");bitToChar(cBit, mingWen, 64);}void bitToHex(char *output, int *input, int length) {int i;for(i=0;i<length/4;i++){output[i]=0;}for(i=0;i<length/4;i++){output[i]=input[4*i]+input[4*i+1]*2+input[4*i+2]*4+input[4*i+3]*8;if(output[i]%16>9){output[i]=output[i]%16+'7';}elseoutput[i]=output[i]%16+'0';}}void hexToBit(int *output, char *input,int length) {int i;for(i=0;i<length;i++){if(input[i/4]<='9'){output[i]=((input[i/4]-'0')>>(i%4))&0x01;}else{output[i]=((input[i/4]-'7')>>(i%4))&0x01;}} }int main(){int mingBit[64] = {0};char ciphertext[16];int keyBit[64] = {0};char mingWen[8]="lkw23333";char key[8]="ssssssss";char deKey[8];printf("明文為:\n");for(int i = 0; i < 8; ++i){printf("%c", mingWen[i]);}printf("\n");charToBit(mingWen, mingBit, 64);charToBit(key, keyBit, 64);doDes(mingBit, ciphertext, keyBit);printf("加密后:\n");for(int i = 0; i < 16; ++i){printf("%c", ciphertext[i]);}printf("\n");printf("請輸入密鑰解密:");gets(deKey);charToBit(deKey, keyBit, 64);deDes(mingWen, ciphertext, keyBit);printf("明文為:\n");for(int i = 0; i < 8; ++i){printf("%c", mingWen[i]);}printf("\n");return 0; }總結(jié)
以上是生活随笔為你收集整理的DES算法C语言实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。