博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
DES加密系统的实现
阅读量:6331 次
发布时间:2019-06-22

本文共 6745 字,大约阅读时间需要 22 分钟。

这是一个高内聚低耦合可复用的DES加密系统的实现。

Github 链接:

 

要实现加密系统,先考虑数据的基本单位。

在DES加密中,数据是以64位为一组的(unsigned long long),我们称它为Bit。

加密过程中会对Bit做位移操作(左移、右移、循环左移、循环右移),也会做位运算(And、Or、Xor),还会做分割以及合并等操作。

我们设计一个类Bit来封装这些操作,作为数据的基本单位。

1 /*  2     表示64位以下的数据  3     可以做常见的位运算  4 */  5 class Bit {  6 private:  7     unsigned long long bit;// 表示数据,最多64位  8     int size;// 表示数据的位数,不超过64位  9 public: 10     // 值为0的64位数据 11     Bit(); 12  13     // 值为_bit的64位数据 14     Bit(unsigned long long _bit); 15  16     // 值为_bit的n位数据,当n>64位时截断 17     Bit(unsigned long long _bit, int n); 18  19     Bit(const Bit& b); 20     Bit& operator=(Bit& b); 21     //Bit& operator=(unsigned char num); 22      23     // 由byte构造8位Bit对象 24     void Byte(unsigned char num); 25  26     // 直接左移d位 27     void LeftShift(int d); 28  29     // 循环左移d位 30     void LeftRotate(int d); 31  32     // 直接右移d位 33     void RightShift(int d); 34  35     // 循环右移d位 36     void RightRotate(int d); 37  38     // 将第pos位设置为1 39     // pos从左向右从0开始计数,超过size位时无效 40     void Set(int pos); 41  42     // 将所有位都设置为1 43     void Set(); 44  45     // 将第pos位设置为0 46     // pos从左向右从0开始计数,超过size位时无效 47     void Reset(int pos); 48  49     // 将所有位都设置为0 50     void Reset(); 51  52     // 将第pos位取反 53     // pos从左向右从0开始计数,超过size位时无效 54     void Flip(int pos); 55  56     // 将所有位都取反 57     void Flip(); 58  59     // 当所有位都为0时返回true 60     bool None(); 61  62     // 当任意位为1时返回true 63     bool Any(); 64  65     // 统计所有位中1的个数 66     int Count(); 67  68     // 数据的有效位数 69     int Size(); 70  71     // 当第pos位的值为1时返回true 72     // pos从左向右从0开始计数,超过size位时无效 73     bool operator[](int pos); 74  75     // 将数据以unsigned long long的形式返回 76     unsigned long long ToULL(); 77  78     // 将所有二进制位以二进制串形式返回 79     std::string ToString(); 80  81     // 静态方法,将数据bit从中间分割为两份数据 82     static std::pair
Split(Bit bit); 83 84 // 静态方法,把数据bit平分为n份,n为偶数,bit的size能被n整除 85 static std::vector
Split(Bit bit, int n); 86 87 // 静态方法,将两份数据合并为一份数据 88 static Bit Merge(Bit L, Bit R); 89 90 // 静态方法,将Bit数组中从L到R之间的数据合并为一份数据 91 static Bit Merge(Bit b[], int L, int R); 92 93 // 静态方法,求两份数据的异或值 94 static Bit Xor(Bit x, Bit y); 95 96 // 静态方法,求两份数据的OR 97 static Bit Or(Bit x, Bit y); 98 99 // 静态方法,求两份数据的AND100 static Bit And(Bit x, Bit y);101 };
Bit类

 

DES加密过程的原理其实就是16轮迭代,而迭代过程中有两个重要的处理:子密钥生成和f函数。

所以先不考虑主加密过程,考虑子密钥和f函数的抽象。

虽然子密钥有16之多,但是我们只要有了主密钥就可以生成全部的16个子密钥。

我们把这个过程抽象出来,即输入主密钥,得到一个装有16个子密钥的动态数组:

1 /*2     主密钥产生子密钥的接口3     单例模式4 */5 class IKeyManager :public Uncopyable {6 public:7     // 通过主密钥产生子密钥8     virtual std::vector
GetKeys(Bit MasterKey) = 0;9 };
IKeyManager接口

 

接下来考虑f函数,它接受一个32位的数据和一个48位的子密钥,返回32位的加密数据。

1 /* 2     DES中f函数的接口 3     单例模式 4     其值通过32位的数据与48位的子密钥计算而来 5 */ 6 class IFunction :public Uncopyable { 7 public: 8     // f函数 9     // bit为32位的R_{i-1},Key为48位的K_i10     virtual Bit ProcessKey(Bit bit, Bit Key) = 0;11 };
IFunction接口

 

有了这两个类,主加密过程就容易实现了。

考虑到主加密过程一次只能处理64位的数据,而实际应用中要多次调用主加密过程来加密长数据。

因此为了避免重复计算子密钥,要在调用主加密过程之前先设置好主秘钥。

解密操作是加密操作的逆操作,所以放在一起实现。

1 /* 2     Data Encryption Standard 接口 3     继承此接口的派生类可以完成以下操作: 4     1-接受一个主密钥 5     2-对一组数据加密 6     3-对一组数据解密 7 */ 8 class IDes { 9 public:10     // 将64位的key设置为主密钥11     virtual void SetMasterKey(Bit key) = 0;12     13     // 加密明文组dat14     virtual Bit Encryption(Bit dat) = 0;15     16     // 解密密文组dat17     virtual Bit Decryption(Bit dat) = 0;18 };
IDes接口

 

这样一来,DES的框架就准备好了,实现的时候有两个较复杂的逻辑:置换表操作和S-Box取值操作。

因此单独把这两个操作抽象出来。设计一个类表示置换表,一个类管理置换表,一个类表示S-Box,一个类管理S-Box。

1 /* 2     置换表接口 3 */ 4 class IPermutationTable { 5 public: 6     // 置换表中元素个数 7     virtual int Size() = 0; 8  9     // 获取表中第pos个元素10     // pos从0开始计数11     virtual int Get(int pos) = 0;12 };
IPermutationTable接口
1 /* 2     DES中置换表的管理器接口 3     单例模式 4     它管理所有DES中要用到的置换表 5 */ 6 class IPmtTableManager :public Uncopyable { 7 public: 8     // 获取初始置换表IP 9     virtual IPermutationTable* GetIPTable() = 0;10 11     // 获取逆初始置换表IP-112     virtual IPermutationTable* GetIPRevTable() = 0;13     14     // 获取扩增排列表E15     virtual IPermutationTable* GetETable() = 0;16     17     // 获取缩减排列表P18     virtual IPermutationTable* GetPTable() = 0;19     20     // 获取密钥排列PC-121     virtual IPermutationTable* GetPC1Table() = 0;22     23     // 获取密钥排列PC-224     virtual IPermutationTable* GetPC2Table() = 0;25 };
IPmtTableManager接口
1 // S-Box的接口2 class ISBox {3 public:4     // 通过6位数据pos获取S-Box中的值5     virtual Bit Get(Bit pos) = 0;6 7     // 通过指定的坐标(i,j)获取S-Box中的值8     virtual Bit Get(int i, int j) = 0;9 };
ISBox接口
1 /* 2     S-Box管理器的接口 3     单例模式 4     它能够返回指定编号的S-Box 5 */ 6 class ISBoxManager :public Uncopyable { 7 public: 8     // 返回指向编号为i的S-Box的指针 9     virtual SBox* GetSBox(int i) = 0;10 };
ISBoxManager接口

 

只有置换表还不够,置换操作也是一个较复杂的操作,应该单独抽象出来处理。

1 /* 2     置换操作的接口 3     单例模式 4 */ 5 class IPermutationManager :public Uncopyable { 6 public: 7     // 用置换表table对数据bit进行置换 8     virtual Bit Permutation(Bit bit, IPermutationTable* table) = 0; 9     // 用置换表table对数据bit进行逆置换10     virtual Bit InversePermutation(Bit bit, IPermutationTable* table) = 0;11 };
IPermutationManager接口

 

如此一来,在添加具体实现细节以后,DES主加密过程就能顺利实现了。

为了加密长数据,我们为之前的代码套上一层外壳。

用一个类来与用户进行交互,使它可以以用户指定的分组方式来对数据分组并调用主加密过程。

/*    加密器接口*/class IEncryptor {public:    // 分组操作方案    enum Type {        ECB, CBC, CFB, OFB    };    // 加密字符串     virtual std::vector
EncryptString(const std::string& string, Bit MasterKey, Type type) = 0; // 解密字符串 virtual std::string DecryptString(const std::vector
& bins, Bit MasterKey, Type type) = 0; // 加密二进制串 virtual std::vector
EncryptBinary(const std::vector
& bins, Bit MasterKey, Type type) = 0; // 解密二进制串 virtual std::vector
DecryptBinary(const std::vector
& bins, Bit MasterKey, Type type) = 0; // 加密文件 virtual std::vector
EncryptFile(char *filename, Bit MasterKey, Type type) = 0; // 解密文件 virtual std::vector
DecryptFile(char *filename, Bit MasterKey, Type type) = 0; // 保存二进制串到文件 virtual void SaveBinaryAsFile(const std::vector
& bins, char *filename) = 0;};
IEncryptor接口

 

最后将具体的分组过程实现即可。

1 /*2     区块加密法的操作模式接口3 */4 class IMode :public Uncopyable {5 public:6     virtual std::vector
EncryptBinary(IDes* des, const std::vector
& bins, Bit MasterKey) = 0;7 virtual std::vector
DecryptBinary(IDes* des, const std::vector
& bins, Bit MasterKey) = 0;8 };
IMode接口

 

posted on
2014-09-19 16:48 阅读(
...) 评论(
...)

转载于:https://www.cnblogs.com/zinthos/p/3981837.html

你可能感兴趣的文章
top命令
查看>>
javascript的作用域
查看>>
新形势下初创B2B行业网站如何经营
查看>>
初心大陆-----python宝典 第五章之列表
查看>>
java基础学习2
查看>>
sysbench使用笔记
查看>>
有关电子商务信息的介绍
查看>>
NFC·(近距离无线通讯技术)
查看>>
nginx 禁止某个IP访问立网站的设置方法
查看>>
多线程基础(三)NSThread基础
查看>>
PHP的学习--Traits新特性
查看>>
ubuntu下,py2,py3共存,/usr/bin/python: No module named virtualenvwrapper错误解决方法
查看>>
Ext.form.field.Number numberfield
查看>>
异地多活数据中心项目
查看>>
Linux文件夹分析
查看>>
解决部分月份绩效无法显示的问题:timestamp\union al\autocommit等的用法
查看>>
nginx 域名跳转 Nginx跳转自动到带www域名规则配置、nginx多域名向主域名跳转
查看>>
man openstack >>1.txt
查看>>
linux几大服务器版本大比拼
查看>>
在BT5系统中安装postgresQL
查看>>