DES算法(C++实现)
概述
DES算法的本质就是置换。通过多轮次多变化的置换将64bit的数据加密成密文,从而达到除了暴力破解(遍历密钥)之外没有其他(足够高效的)解法的目的。
DES算法的相关原理网上都有比较详尽的描述,理解起来并不困难,只是实现起来稍有点麻烦,一不小心就有可能出错。
在我的实现的过程中主要参考了网上的一篇 博客,实现之后的结果可以正常加密出结果,解密之后也可以得出原文,同时具有雪崩效应。
实验环境
- 系统:Windows 10 家庭中文版
- IDE:Visual Studio 2015 Community
遇到的问题
实现DES算法之后可以正常加密出结果,解密之后也可以得出原文,同时具有雪崩效应,但是找了两份其他人的DES算法实现一对比,发现三份代码的加密结果都不一样(使用相同的key与加密原文)。。。所以必然有人的实现方法有问题。个人估计问题所在最有可能有以下几个方面:
对置换表的处理不同。例如置换表中第一个元素保存58,那么有人处理为原文第58位置换到此处,而有人处理为原文第1位置放到置换表的第58位。
S盒处的置换的逻辑有误。此处比较复杂,有可能出现失误,又因为加密解密的区别只是逆用密钥,所以也有可能出错了能够正常加密解密。
有人使用了非正统的置换表。按理说DES算法是公开公认的算法,所有人使用的置换表应该是相同的,才可以正常地解密。但是不排除有人使用了另一个不同却也可以对自己的加密数据进行加密解密的置换表的情况。
实验结果
由于时间精力有限,所以没有继续往下钻研,毕竟这次实验的目的只是理解DES加密算法的原理与实现,真正使用的时候大多情况下还是调用发展成熟完善的库函数的。这里就不给更多说明啦,下面丢代码,代码里加了大量中文注释便于理解与回忆。代码一共3个文件:
DES.h
DES.cpp
Main.cpp
(测试用例)
如果想直接要 VS Project 的话点击 这里 进行下载。
DES.h
#define BIT bool
class DES {
public:
static void des_encrypt(BIT input[64], BIT output[64], BIT key[64]);
static void des_decrypt(BIT input[64], BIT output[64], BIT key[64]);
};
DES.m
#include <iostream>
#include "DES.h"
using namespace std;
#define BIT bool
BIT keys[16][48];
// 函数声明
static void permute(BIT *input, BIT *output, int *box, int length);
static void inital_permute(BIT *input, BIT *output);
static void final_permute(BIT *input, BIT *output);
static void generate_keys(BIT key[64]);
static void encrypt_every_turn(BIT left_data[32], BIT right_data[32], BIT key[48], int turn);
static void encrypt_or_decrypt(BIT input[64], BIT output[64], BIT key[64], bool isEncrypt);
// 加密
void DES::des_encrypt(BIT input[64], BIT output[64], BIT key[64]) {
encrypt_or_decrypt(input, output, key, true);
}
// 解密
void DES::des_decrypt(BIT input[64], BIT output[64], BIT key[64]) {
encrypt_or_decrypt(input, output, key, false);
}
// 封装好的置换函数
void permute(BIT *input, BIT *output, int *box, int length) {
for (int i = 0; i < length; ++i) {
output[i] = input[box[i] - 1];
}
}
// 初始置换
void inital_permute(BIT *input, BIT *output) {
static int IP[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 };
permute(input, output, IP, 64);
}
// 最终置换
void final_permute(BIT *input, BIT *output) {
static int FP[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 };
permute(input, output, FP, 64);
}
// 生成加密密钥
void generate_keys(BIT key[64]) {
// KP:密钥置换选择1(64->56)
static int KP[56] = {
57 , 49 ,