DES算法C++程序设计和实现

1 算法原理概述

Data Encryption Standard (DES) 是一种典型的对称密钥算法,采用块加密方法,它以64位为分组长度,64位一组的明文作为算法的输入,通过与密钥运算和一系列复杂的操作,输出同样64位长度的密文,用同一密钥可以解密,所以该算法所有的保密性依赖于密钥,认为只有持有加密所用的密钥才能解密密文。DES采用64位密钥,但由于每8位中的最后1位用于奇偶校验,实际有效密钥长度为56位。DES算法的基本过程是换位和置换

2 总体结构

在这里插入图片描述
C = Ek(M) = IP-1·W·T16·T15·…·T1·IP(M).

3 模块分解

C = DES(M, K)
流程:

  • 初始置换IP -> M0 = IP(M) = L0R0
  • 16轮迭代T-> L16R16 = T16(L0R0)
    • T -> LiRi = T(Li-1Ri-1) 其中Li= Ri-1, Ri= Li-1⊕f(Ri-1, Ki), i = 1 … 16.
      • f -> f(Ri-1, Ki) (Feistel轮函数)
        • 将长度为32位的串Ri-1 作E-扩展 E(Ri-1)
        • E(Ri-1)⊕Ki
          • 子密钥的生成
        • S-box 平均分成8个分组分别经过8个不同的S-盒进行 6-4 转换
        • P-置换
  • 左右置换W
  • 逆置换IP-1 -> C = IP-1(R16L16)

根据以上流程的包含关系,分解得到的主要模块为:
在这里插入图片描述
其中最主要的模块为子密钥生成和Feistel轮函数。
在这里插入图片描述
此外,从DES的功能上来分,可以分为加密和解密两个大的模块。
在这里插入图片描述
(其他具体细节见源代码)

4 数据结构

涉及到位操作的许多部分可以利用c++中的bitset方便进行;
此外,置换表可以用一维数组表示;
每个S_BOX为一个二维数组,所以S_BOX可以用三维数组表示;

5 编译运行结果

(1)对64位数据加密和解密,并将结果输出:
在这里插入图片描述
在这里插入图片描述
(2)对图片文件进行加密和解密
在这里插入图片描述
在这里插入图片描述
加密和解密后,文件下多出两个文件,分别是密文(16进制数据)和解密后的图片文件,他们的文件大小都相同,打开也能正确显示原图。
在这里插入图片描述
在这里插入图片描述
补充:DES 算法中,原始明文被分为64位的明文块进行加密,最后一块不足64位 ,则补齐为64位后再进行加密。本次实验没有进行填充处理,但实际上,原始明文消息按PKCS#5 (RFC 8018) 规范进行字节填充:原始明文消息最后的分组不够8个字节(64位) 时,在末尾以字节填满,填入的字节取值相同,取值都为需填充的字节数目;原始明文消息刚好分组完全时,在末尾填充8个字节(即增加一个完整分组),字节取值都是08(因为填充了8个字节)。

6 源代码

DES.hpp

// DES.hpp
#include <bitset>
using std::bitset;
 
class DES
{
   
public:
	DES();
	bitset<64> encrypt(const bitset<64>& plain, const bitset<64>& key);
	bitset<64> decrypt(const bitset<64>& plain, const bitset<64>& key);
	~DES();
private:
	bitset<48> subKeys[16];
	static const int ip[64]; // 初始置换表

	//密钥生成所用置换表
	static const int PC_1[56]; // PC-1置换表
	static const int PC_2[48]; // PC-2压缩置换表
	
	// Feistel轮函数所用置换表
	static const int E[48]; // 拓展置换表
	static const int P[32]; // P置换表
	static int S_BOX[8][4][16]; // 8个S-BOX

	// initial permutation
	bitset<64> IP(const bitset<64>& plain);
	// IP逆置换
	bitset<64> IP_1(const bitset<64>& bits);
	// Feistel 轮函数
	bitset<32> f(const bitset<32>& right, const bitset<48>& subKey);
	// 生成子密钥
	void generateSubKeys(const bitset<64>& key);
};

DES.cpp

// DES.cpp
#include "DES.hpp"

// 初始置换表
const int DES::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 };


/*---------------------密钥生成所用置换表---------------------*/

// PC-1置换表
const int DES::PC_1[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};
// PC-2压缩置换表
const int DES::PC_2[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};


/*---------------------Feistel轮函数所用置换表---------------------*/

// 拓展置换表
const int DES::E[48] = {
   32, 
  • 4
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值