吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2864|回复: 13
上一主题 下一主题
收起左侧

[C&C++ 原创] DES算法的C语言实现

  [复制链接]
跳转到指定楼层
楼主
LegendSaber 发表于 2021-10-24 12:40 回帖奖励
本帖最后由 LegendSaber 于 2021-10-24 12:52 编辑

       曾经学习DES算法时候写过的一份C语言实现的DES加解密算法。现在提供给大家参考
       首先,由于DES是在比特层面对输入进行加密的。所以,首先需要做到将输入的字符与其二进制形式的互相转换,这部分代码在CChar中实现
[C] 纯文本查看 复制代码
#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中定义
[C] 纯文本查看 复制代码
#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加密
[C] 纯文本查看 复制代码
#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的加密解密

DES.rar

113.48 KB, 下载次数: 61, 下载积分: 吾爱币 -1 CB

免费评分

参与人数 4威望 +1 吾爱币 +22 热心值 +4 收起 理由
cimery + 1 + 1 今天实验课要用到DES,用起来很懵!前来学习一下博主的成果~还没理解
笙若 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
andi526 + 1 我很赞同!
苏紫方璇 + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!

查看全部评分

本帖被以下淘专辑推荐:

  • · Aarow|主题: 988, 订阅: 304

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

推荐
 楼主| LegendSaber 发表于 2021-10-24 12:53 |楼主
Eaglecad 发表于 2021-10-24 12:51
感谢分享,要是再讲解下原理啥的更好

哦。。那是因为这种经典的密码算法原理网上真的特别特别多。。再写的话挺多余的。。。。
推荐
 楼主| LegendSaber 发表于 2021-10-24 13:18 |楼主
nanaqilin 发表于 2021-10-24 13:07
我早就不是学生了,我是社会人事,现在做项目都是用openssl

实际项目肯定是调包啊。。。谁能写的比那些人好啊。。。
沙发
Eaglecad 发表于 2021-10-24 12:51
4#
nanaqilin 发表于 2021-10-24 12:58
你这个挺厉害的,我都是用openssl来实现加解密
5#
 楼主| LegendSaber 发表于 2021-10-24 13:00 |楼主
nanaqilin 发表于 2021-10-24 12:58
你这个挺厉害的,我都是用openssl来实现加解密

谁还不是被挂科的恐惧逼了一把。。。

点评

当年被密码学考试支配的恐惧  详情 回复 发表于 2021-10-24 15:34
6#
nanaqilin 发表于 2021-10-24 13:07
LegendSaber 发表于 2021-10-24 13:00
谁还不是被挂科的恐惧逼了一把。。。

我早就不是学生了,我是社会人事,现在做项目都是用openssl
8#
大脑组织残缺 发表于 2021-10-24 13:34
DES,RSA 网络安全课上做过
9#
yacc 发表于 2021-10-24 15:34
LegendSaber 发表于 2021-10-24 13:00
谁还不是被挂科的恐惧逼了一把。。。

当年被密码学考试支配的恐惧
10#
谁的坏叔叔 发表于 2021-10-24 19:39
有易语言的吗
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-23 20:48

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表