DES算法的C语言实现

曾经学习DES算法时候写过的一份C语言实现的DES加解密算法。现在提供给大家参考
首先,由于DES是在比特层面对输入进行加密的。所以,首先需要做到将输入的字符与其二进制形式的互相转换,这部分代码在CChar中实现

#include "CChar.h"
 
void CharToBit(char input[], char output[])
{
        int i = 0, j = 0, k = 0;
         
        for (i = 0; i < 8; i++)
        {
                for (j = 0; j < 8; j++)
                {
                        k = 7 - j;
                        output[i * 8 + j] = (input[i] >> k) & 0x1;
                }
        }
}
 
void BitToChar(char input[], char output[])
{
        int i = 0, j = 0, k = 0;
 
        for (i = 0; i < 8; i++)
        {
                for (j = 0; j < 8; j++)
                {
                        k = 7 - j;
                        output[i] |= (input[i * 8 + j] << k);
                }
        }
}

其次,为了完成DES加密需要用到的密钥以及置换表等等这部分内容在table.h中定义

#ifndef __MY_TABLE_
#define __MY_TABLE_
 
//存储程序所需要的表与密钥
 
//初始置换表IP
const char IP_Table[64] = { 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, 
                            56,48,40,32,24,16,8,0, 
                            58,50,42,34,26,18,10,2, 
                            60,52,44,36,28,20,12,4, 
                            62,54,46,38,30,22,14,6};  
//逆初始置换表IP^-1 
const char IP_1_Table[64] = { 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, 
                              32,0,40,8,48,16,56,24};
//扩展表E
const char E_Table[48] = { 31, 0, 1, 2, 3, 4,
                           3, 4, 5, 6, 7, 8,
                           7, 8, 9, 10, 11, 12,
                           11, 12, 13, 14, 15, 16,
                           15, 16, 17, 18, 19, 20,
                           19, 20, 21, 22, 23, 24,
                           23, 24, 25, 26, 27, 28,
                           27, 28, 29, 30, 31, 0};
//置换表P
const char P_Table[32] = { 15, 6, 19, 20, 11, 27, 16,
                           0, 14, 22, 25, 4, 17, 30, 9,
                           1, 7, 23, 13, 31, 26, 2, 8,
                           18, 12, 29, 5, 21, 10, 3, 24};
//S盒
const char S[8][4][16] =
                {
                    //S1
                    {{14,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}}, 
                    //S2 
                    {{14,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}},
                    //S3 
                    {{14,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}}, 
                    //S4 
                    {{14,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}}, 
                    //S5 
                    {{14,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}}, 
                    //S6 
                    {{14,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}}, 
                    //S7 
                    {{14,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}}, 
                    //S8 
                    {{14,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}}
                };
 
//置换选择1        
int PC_1[56] = { 56,48,40,32,24,16,8, 
                 0,57,49,41,33,25,17, 
                 9,1,58,50,42,34,26, 
                 18,10,2,59,51,43,35, 
                 62,54,46,38,30,22,14, 
                 6,61,53,45,37,29,21, 
                 13,5,60,52,44,36,28, 
                 20,12,4,27,19,11,3}; 
   
//置换选择2 
int PC_2[48] = { 13,16,10,23,0,4,2,27, 
                 14,5,20,9,22,18,11,3, 
                 25,7,15,6,26,19,12,1, 
                 40,51,30,36,46,54,29,39, 
                 50,44,32,46,43,48,38,55, 
                 33,52,45,41,49,35,28,31};
                 
//循环左移的位数
const char RoundLeft[16] = {1, 1, 2, 2,
                            2, 2, 2, 2,
                            1, 2, 2, 2,
                            2, 2, 1, 1};
//加密密钥                     
const char cKey[9] = {"12345678"};
char bKey[56] = { 0 };
//IV向量
char cIV[9] = {"IVVector"};
#endif

最后就是在主函数中对输入进行16轮的DES加密

#include <cstdio>
#include <cstring>
#include "table.h"
#include "CChar.h"
 
void DESAlgorithm(char cOrigData[]);        //DES算法主体
//对左边32比特进行加密
void XOREncryptLeft(char cLeftChar[], char cRightChar[], int iIndex);
void InitBitKey();        //将密钥初始化为比特形式且进行置换       
void EncryptByCBC(char cOrigData[], char cOrigData2[]);        //采用CBC模式加密
void EncryptByCFB(char cOrigData[], char cOrigData2[]); //采用CFB模式加密
 
int main()
{
        char cOrigData[9] = {"1900Code"};
        char cOrigData2[9] = {"I 1900"};
         
        printf("加密前的数据: %s %s\n", cOrigData, cOrigData2);
         
        EncryptByCBC(cOrigData, cOrigData2);
        EncryptByCFB(cOrigData, cOrigData2);
         
        getchar();
        return 0;
}
 
void EncryptByCFB(char cOrigData[], char cOrigData2[])
{
        InitBitKey();
        DESAlgorithm(cIV);
         
        for (int i = 0; i < 9; i++) cOrigData[i] ^= cIV[i];
        printf("CFB模式加密后的数据:%s ", cOrigData);
         
        InitBitKey();
        DESAlgorithm(cOrigData);
         
        for (int i = 0; i < 9; i++) cOrigData2[i] ^= cOrigData[i];
        printf("%s\n", cOrigData2);
         
         
        for (int i = 0; i < 9; i++) cOrigData2[i] ^= cOrigData[i];
        InitBitKey();
        DESAlgorithm(cOrigData);
        for (int i = 0; i < 9; i++) cOrigData[i] ^= cIV[i];
        printf("CFB模式解密的数据:%s %s\n", cOrigData, cOrigData2);
        InitBitKey();
        DESAlgorithm(cIV);
}
 
void EncryptByCBC(char cOrigData[], char cOrigData2[])
{
        InitBitKey();
        for (int i = 0; i < 9; i++) cOrigData[i] ^= cIV[i];
        DESAlgorithm(cOrigData);
 
        InitBitKey();
        for (int i = 0; i < 9; i++) cOrigData2[i] ^= cOrigData[i];
        DESAlgorithm(cOrigData2);
        printf("CBC模式加密后结果: %s %s\n", cOrigData, cOrigData2);
         
        InitBitKey();
        DESAlgorithm(cOrigData2);
        for (int i = 0; i < 9; i++) cOrigData2[i] ^= cOrigData[i];
         
        InitBitKey();
        DESAlgorithm(cOrigData);
        for (int i = 0; i < 9; i++) cOrigData[i] ^= cIV[i];
        printf("CBC模式解密后的数据: %s %s\n", cOrigData, cOrigData2);
}
 
void DESAlgorithm(char cOrigData[])
{
        char cLeft[32] = { 0 }, cRight[32] = { 0 }, cOrigChar[64] = { 0 };
        char cTmp = 0, cOrigCpyChar[64] = { 0 };
 
        CharToBit(cOrigData, cOrigChar);
         
        memset(cOrigCpyChar, 0, sizeof(cOrigCpyChar));
        memcpy(cOrigCpyChar, cOrigChar, 64);        //进行初始置换
        for (int i = 0; i < 64; i++)
        {
                cOrigChar[i] = cOrigCpyChar[IP_Table[i]];
        }
         
        for (int i = 0; i < 32; i++)
        {
                cLeft[i] = cOrigChar[i];
                cRight[i] = cOrigChar[32 + i];
        }
         
        for (int i = 0; i < 16; i++)        //进行16轮的加密
        {
                XOREncryptLeft(cLeft, cRight, i);
                 
                //除最后一轮,交换左右两边的比特
                if (i < 15)
                {
                        for (int j = 0; j < 32; j++)
                        {
                                cTmp = cLeft[j];
                                cLeft[j] = cRight[j];
                                cRight[j] = cTmp;
                        }
                }
        }
         
        for (int i = 0; i < 32; i++)
        {
                cOrigChar[i] = cLeft[i];
                cOrigChar[32 + i] = cRight[i];
        }
 
        memset(cOrigCpyChar, 0, sizeof(cOrigCpyChar));
        memcpy(cOrigCpyChar, cOrigChar, 64);        //进行逆初始置换
        for (int i = 0; i < 64; i++)
        {
                cOrigChar[i] = cOrigCpyChar[IP_1_Table[i]];
        }
         
        memset(cOrigData, 0, sizeof(cOrigData));
        BitToChar(cOrigChar, cOrigData);
}
 
void XOREncryptLeft(char cLeftChar[], char cRightChar[], int iIndex)
{
        char cExtendChar[48] = { 0 };
        int i = 0, moveNum = 0, col = 0, row = 0, j = 0, k = 0, l = 0;
        char cLeftKey[28] = { 0 }, cRightKey[28] = { 0 };
        char bEncryptKey[48] = { 0 };
        char bSData[32] = { 0 };
        char cSData = 0;
         
        //进行扩展E置换
        for (i = 0; i < 48; i++)
        {
                cExtendChar[i] = cRightChar[E_Table[i]];
        }
         
        for (i = 0; i < 28; i++)
        {
                cLeftKey[i] = bKey[i];
                cRightKey[i] = bKey[28 + i];
        }
         
        moveNum = RoundLeft[iIndex];
        for (i = 0; i < 28 - moveNum; i++)
        {
                cLeftKey[i] = cLeftKey[i + moveNum];
                cRightKey[i] = cRightKey[i + moveNum];
        }
         
        for (i = 28 - moveNum; i < 28; i++)
        {
                cLeftKey[i] = 0;
                cRightKey[i] = 0;
        }
         
        for (i = 0; i < 28; i++)
        {
                bKey[i] = cLeftKey[i];
                bKey[28 + i] = cRightKey[i];
        }
         
        for (i = 0; i < 48; i++) bEncryptKey[i] = bKey[PC_2[i]];
         
        for (i = 0; i < 48; i++) cExtendChar[i] |= bEncryptKey[i];
         
        for (i = 0; i < 8; i++)
        {
                row = (cExtendChar[i * 8] - '0') * 2 + (cExtendChar[i * 8 + 5] - '0');
                col = (cExtendChar[i * 8 + 1] - '0') * 8 + (cExtendChar[i * 8 + 2] - '0') * 4
                        + (cExtendChar[i * 8 + 3] - '0') * 2 + (cExtendChar[i * 8 + 4] - '0');
                         
                cSData = S[iIndex][row][col];
                if (cSData >= 8)
                {
                        bSData[i * 4] = 1;
                        cSData -= 8;
                }
                 
                if (cSData >= 4)
                {
                        bSData[i * 4 + 1] = 1;
                        cSData -= 4;
                }
                 
                if (cSData >= 2)
                {
                        bSData[i * 4 + 2] = 1;
                        cSData -= 2;
                }
                 
                if (cSData == 1) bSData[i * 4 + 3] = 1;
        }
         
        for (i = 0; i < 32; i++) cLeftChar[i] |= bSData[i];
}
 
void InitBitKey()
{
        int i = 0, j = 0, k = 0;
        char bCpyKey[56] = { 0 };
         
        for (i = 0; i < 7; i++)
        {
                for (j = 0; j < 8; j++)
                {
                        k = 7 - j;
                        bKey[i * 8 + j] = (cKey[i] >> k) & 0x1;
                }
        }
         
        memset(bCpyKey, 0, sizeof(bCpyKey));
        memcpy(bCpyKey, bKey, 56);
        for (i = 0; i < 56; i++)
        {
                bKey[i] = bCpyKey[PC_1[i]];
        }
}

可以看到最终的输出,程序成功对输入的字符进行DES的加密解密源码链接:https://pan.baidu.com/s/1S2K6tpzUUnDvbOjnA4cV1A
提取码:1024

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

飞天的大鹅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值