S-DES加密

  1 #include <cstdio>
  2 #include <iostream>
  3 #include <fstream>
  4 #include <algorithm>
  5 #include <vector>
  6
  7 class S_DES {
  8 private:
  9     typedef unsigned int uint;
 10     typedef unsigned char uchar;
 11     typedef std::pair<unsigned int, unsigned int> PII;
 12     typedef std::pair<PII, PII> PPI;
 13     typedef std::vector<unsigned int> VI;
 14     typedef std::vector<VI> VVI;
 15     typedef std::vector<unsigned char> VC;
 16
 17     const static VI P_10;
 18     const static VI P_8;
 19     const static VI P_4;
 20     const static VI IP;
 21     const static VI IP_1;
 22     const static VI EP;
 23     const static VVI S_1;
 24     const static VVI S_2;
 25
 26     // MakePII
 27     inline PII MakePII(uint L, uint R) {
 28         return std::make_pair(L, R);
 29     }
 30
 31     // MakePPI
 32     inline PPI MakePPI(uint A, uint B, uint C, uint D) {
 33         return std::make_pair(std::make_pair(A, B), std::make_pair(C, D));
 34     }
 35
 36     // 置换,长度为X
 37     int Permutation(uint Bit, int X, const VI &P) {
 38         uint res = 0;
 39         int n = P.size();
 40         for (int i = 0; i < n; i++) {
 41             res <<= 1;
 42             if (Bit & (1 << (X - P[i]))) res |= 1;
 43         }
 44         return res;
 45     }
 46
 47     // 以X为单位分割二进制数为两份
 48     PII Split(uint Bit, int X) {
 49         uint L = 0, R = 0;
 50         uint mask = (1 << X) - 1;
 51         R = Bit & mask;
 52         L = Bit >> X;
 53         return MakePII(L, R);
 54     }
 55
 56     // 将四位二进制数转化为S-BOX的坐标
 57     PII GetBoxXY(uint Bit) {
 58         uint x = 0, y = 0;
 59         if (Bit&(1 << 3)) x |= 1;
 60         if (Bit&(1 << 2)) y |= 1;
 61         x <<= 1;
 62         y <<= 1;
 63         if (Bit&(1 << 0)) x |= 1;
 64         if (Bit&(1 << 1)) y |= 1;
 65         return MakePII(x, y);
 66     }
 67
 68     // 将八位二进制数转化为S-BOX的坐标
 69     PPI GetExBox(uint Bit) {
 70         PII pii = Split(Bit,4);
 71         PII xy1 = GetBoxXY(pii.first);
 72         PII xy2 = GetBoxXY(pii.second);
 73         return MakePPI(xy1.first, xy1.second, xy2.first, xy2.second);
 74     }
 75
 76     // 合并两个长度为X的二进制数
 77     uint Merge(uint lBit, uint rBit, int X) {
 78         return (lBit << X) | rBit;
 79     }
 80
 81     // 将长度为L的二进制数,循环左移X次
 82     uint LS(uint Bit, int L, int X) {
 83         X %= L;
 84         uint mask = (1 << L) - 1;
 85         uint ans = ((Bit << X) & mask) | (Bit >> (L - X));
 86         return ans;
 87     }
 88
 89     // S-DES 子密码生成过程,MasterKey是10位的主密钥。
 90     PII GetSubPsw(uint MasterKey) {
 91         uint K = Permutation(MasterKey, 10, P_10);// 主密钥K进行P10置换
 92         PII pii = Split(K, 5);                    // 分成左5位右5位
 93         uint L = pii.first;                          //
 94         uint R = pii.second;                      //
 95         L = LS(L, 5, 1);                          // 分别进行LS-1操作
 96         R = LS(R, 5, 1);                          // 其结果一方面作为下一轮的初始值
 97         uint K_1 = Merge(L, R, 5);                // 另一方面进行P8置换
 98         K_1 = Permutation(K_1, 10, P_8);          // 得到K1
 99         L = LS(L, 5, 2);                          // 再分别左循环2位
100         R = LS(R, 5, 2);                          //
101         uint K_2 = Merge(L, R, 5);                  //
102         K_2 = Permutation(K_2, 10, P_8);          // 经过P8置换,得到K2
103         return MakePII(K_1, K_2);
104     }
105
106     // S-DES的f函数
107     uint Function(uint Ipt, uint K) {
108         uint ex = Permutation(Ipt, 4, EP);// E/P扩展及置换。将4位R扩展为8位
109         ex ^= K;                          // 扩展后的8位异或秘钥K
110         PPI ppi = GetExBox(ex);           // 左边4位作为S1盒输入,右边四位作为S2盒输入
111         uint x1 = ppi.first.first;          // 在S1和S2中,第一位与第四位结合形成2位代表S盒的行号
112         uint y1 = ppi.first.second;       // 第二位与第三位结合形成2位代表S盒的列号
113         uint x2 = ppi.second.first;       //
114         uint y2 = ppi.second.second;      //
115         uint s1 = S_1[x1][y1];              // 得到S盒的输出
116         uint s2 = S_2[x2][y2];            //
117         uint res = Merge(s1, s2, 2);      //
118         res = Permutation(res, 4, P_4);   // 进行P4置换,得到f函数的输出
119         return res;
120     }
121
122     // S-DES 加密
123     uint S_DES_Main(uint Plaintext, uint K_1, uint K_2) {
124         Plaintext = Permutation(Plaintext, 8, IP);// 初始置换IP,将8位明文按照置换顺序进行位置变化。
125         PII pii = Split(Plaintext, 4);              // 置换后分
126         uint L0 = pii.first;                      // 左4位L0
127         uint R0 = pii.second;                      // 右4位R0
128         uint L1 = R0;                              // 第一轮运算,R0作为下一轮的L1
129         uint R1 = L0 ^ (Function(R0, K_1));          // R0作为f函数的输入与8位子秘钥K1参与函数运算,运算结构与L0异或,结果作为下一轮的R1
130         uint R2 = R1;                              // 第二轮运算,R1作为下一轮的R2
131         uint L2 = L1 ^ (Function(R1, K_2));       // R1作为f函数的输入与8位子密钥K2参与函数运算,运算结果与L1异或,结果作为下一轮的L2
132         uint res = Merge(L2, R2, 4);              //
133         res = Permutation(res, 8, IP_1);          // 逆置换IP-1
134         return res;
135     }
136 public:
137     // 将数字以二进制形式输出
138     void PrintBinary(uint b) {
139         if (b == 0) {
140             printf("0\n");
141             return;
142         }
143         VI vec;
144         vec.clear();
145         while (b > 0) {
146             if (b & 1) vec.push_back(1);
147             else vec.push_back(0);
148             b >>= 1;
149         }
150         for (auto it = vec.rbegin(); it != vec.rend(); it++) {
151             printf("%d", *it);
152         }
153         printf("\n");
154     }
155
156     // 将二进制字符串转换为数字
157     uint StringToBinary(const std::string &Str) {
158         uint res = 0;
159         uint len = Str.length();
160         for (uint i = 0; i < len; i++) {
161             res <<= 1;
162             if (Str[i] == ‘1‘) res |= 1;
163         }
164         return res;
165     }
166
167     // 加密一个单位的数据
168     uint EncryptInt(uint Text, uint MasterKey) {
169         auto p = GetSubPsw(MasterKey);
170         uint K_1 = p.first;
171         uint K_2 = p.second;
172         uint res = S_DES_Main(Text, K_1, K_2);
173         return res;
174     }
175
176     // 按字符加密一个字符串
177     VI EncryptString(const std::string &Str, uint MasterKey) {
178         VI res;
179         auto p = GetSubPsw(MasterKey);
180         uint K_1 = p.first;
181         uint K_2 = p.second;
182         int len = Str.length();
183         for (int i = 0; i < len; i++) {
184             uint e = S_DES_Main((uint)Str[i], K_1, K_2);
185             res.push_back(e);
186         }
187         return res;
188     }
189
190     // 加密一组vector中的数字
191     VI EncryptVector(const VI &Arr, uint MasterKey) {
192         VI res;
193         auto p = GetSubPsw(MasterKey);
194         uint K_1 = p.first;
195         uint K_2 = p.second;
196         int len = Arr.size();
197         for (int i = 0; i < len; i++) {
198             uint e = S_DES_Main(Arr[i], K_1, K_2);
199             res.push_back(e);
200         }
201         return res;
202     }
203
204     // 加密长度为n的数组中的数字
205     VI EncryptArray(const uint Arr[], int n, uint MasterKey) {
206         VI res;
207         auto p = GetSubPsw(MasterKey);
208         uint K_1 = p.first;
209         uint K_2 = p.second;
210         for (int i = 0; i < n; i++) {
211             uint e = S_DES_Main(Arr[i], K_1, K_2);
212             res.push_back(e);
213         }
214         return res;
215     }
216
217     // 加密一个文件中的数据
218     VI EncryptFile(char FileName[], uint MasterKey) {
219         VI res;
220         std::ifstream fin(FileName, std::ios::binary);
221         if (!fin.is_open()) return res;
222         int n = (int)fin.gcount();
223         uint bit = 0;
224         for (int i = 0; i < n; i++) {
225             char pc;
226             fin.read(&pc, sizeof(uchar));
227             bit <<= 8;
228             bit |= pc;
229             if (i & 1) {
230                 bit = EncryptInt(bit, MasterKey);
231                 res.push_back(bit);
232                 bit = 0;
233             }
234         }
235         if (n & 1) {
236             bit <<= 8;
237             bit = EncryptInt(bit, MasterKey);
238             res.push_back(bit);
239         }
240         return res;
241     }
242
243
244 };
245
246 const S_DES::VI S_DES::P_10{ 3, 5, 2, 7, 4, 10, 1, 9, 8, 6 };
247 const S_DES::VI S_DES::P_8{ 6, 3, 7, 4, 8, 5, 10, 9 };
248 const S_DES::VI S_DES::P_4{ 2, 4, 3, 1 };
249 const S_DES::VI S_DES::IP{ 2, 6, 3, 1, 4, 8, 5, 7 };
250 const S_DES::VI S_DES::IP_1{ 4, 1, 3, 5, 7, 2, 8, 6 };
251 const S_DES::VI S_DES::EP{ 4, 1, 2, 3, 2, 3, 4, 1 };
252 const S_DES::VVI S_DES::S_1{ { 1, 0, 3, 2 },
253                              { 3, 2, 1, 0 },
254                              { 0, 2, 1, 3 },
255                              { 3, 1, 3, 2 } };
256 const S_DES::VVI S_DES::S_2{ { 0, 1, 2, 3 },
257                              { 2, 0, 1, 3 },
258                              { 3, 0, 1, 0 },
259                              { 2, 1, 0, 3 } };
时间: 2024-10-13 12:48:42

S-DES加密的相关文章

C#DES加密解密字符串

1.添加引用 using System.Security.Cryptography; using System.IO; 2.添加默认密匙向量 //默认密钥向量 private static byte[] Keys = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF }; 3.添加加密解密类 /// <summary> /// DES加密字符串 /// </summary> /// <param name="encry

DES加密解密算法

DES加密解密算法 // 仿射变换加解密.cpp : 定义控制台应用程序的入口点. // #include <stdio.h> #include <conio.h> static char key[10], key_a[5], code[8], key_b[5], temp[10], key_aa[8], key_bb[8], l[4], r[4], l_a[4], r_a[4], V[8] = { 0, 1, 0, 1, 0, 1, 0, 1 }, b[8]; char Code

Oracle定义DES加密解密及MD5加密函数

http://blog.csdn.net/xdweleven/article/details/38319351 (1)DES加密函数create or replace functionencrypt_des(p_text varchar2, p_key varchar2) return varchar2 is        v_text varchar2(4000);        v_enc varchar2(4000);        raw_input RAW(128) ;       

pyDes库 实现python的des加密

下载及简介地址:https://twhiteman.netfirms.com/des.html 如需要在python中使用des加密,可以直接使用pyDes库加密,该库提供了CBC和ECB两种加密方式. 1.Windows下安装 下载后pyDes-x.x.x.zip并解压后,里面有setup.py文件,使用命令 setup.py --help可查看详细使用. 你可以使用命令 python setup.py install 命令安装,也可以直接将压缩包内的pyDes.py拷贝到本地的python

des加密解密——java加密,php解密

最近在做项目中,遇到des加密解密的问题. 场景是安卓app端用des加密,php这边需要解密.之前没有接触过des这种加密解密算法,但想着肯定会有demo.因此百度,搜了代码来用.网上代码也是鱼龙混杂,好不容易测试在php这边测试加密和解密成功了.为确保安卓app端提交过来的加密参数能够解密出来,给定安卓人员一个字符串,让他们把des加密后的字符串给我,在php这边解密.结果一看,加密出来的字符串跟我这边加密出来的结果不一致,自然是解密不出来. 要来java的des算法代码,研究加密的过程,其

关于 Des加密(Android与ios 与后台java服务器之间的加密解密)

关于 Des加密(Android与ios  与后台java服务器之间的加密解密) http://blog.sina.com.cn/s/blog_7c8dc2d50101id91.html (2013-04-17 11:47:23)   分类: iPhone开发 最近做了一个移动项目,是有服务器和客户端类型的项目,客户端是要登录才行的,登录的密码要用DES加密,服务器是用Java开发的,客户端要同时支持多平台(Android.iOS),在处理iOS的DES加密的时候遇到了一些问题,起初怎么调都调不

兼容PHP和Java的des加密解密代码分享

这篇文章主要介绍了兼容PHP和Java的des加密解密代码分享,适合如服务器是JAVA语言编写,客户端是PHP编写,并需要des加密解密的情况,需要的朋友可以参考下 php <?php class DES { var $key; var $iv; //偏移量 function DES($key, $iv=0) { $this->key = $key; if($iv == 0) { $this->iv = $key; } else { $this->iv = $iv; } } //加

【Android开发经验】比DES加密更安全的算法——3DES加密算法

转载请注明出处:http://blog.csdn.net/zhaokaiqiang1992 在前面的文章里面,我们讨论了DES算法,同时也明白了如何才能保证不同平台下的加密和解密结果的一致性.但是DES作为出现了很长时间的一种加密算法,随着计算机运算能力的加强,DES加密容易被暴力破解,其安全性变得有点低.于是,为了增强数据的安全性,3DES算法就应运而生了. 3DES,顾名思义,就是对DES加密算法的改进,3DES通过对每个数据进行3次DES加密,从而降低被破解的可能性. 如果我们要使用3DE

【Android开发经验】如何保证Android与服务器的DES加密保持一致

转载请注明出处:http://blog.csdn.net/zhaokaiqiang1992 在我们的应用程序涉及到比较敏感的数据的时候,我们通常会对数据进行简单的加密.在与服务器之间的数据交互中,除了可以使用post请求来增强数据的安全性之外,我们可以使用常见的加密算法,对数据进行加密.今天主要介绍的是DES加密算法. 首先,DES属于一种对称的加密算法,所谓对称,就是说加密和解密使用的都是同一个密钥,那么在我们实际应用的时候,就是指服务器和客户端进行加密解密的时候,使用的是一个相同的密钥.除此

关于Objective-c和Java下DES加密保持一致的方式

转载自:http://www.cnblogs.com/janken/archive/2012/04/05/2432930.html 最近做了一个移动项目,是有服务器和客户端类型的项目,客户端是要登录才行的,登录的密码要用DES加密,服务器是用Java开发的,客户端要同时支持多平台(Android.iOS),在处理iOS的DES加密的时候遇到了一些问题,起初怎么调都调不成和Android端生成的密文相同.最终一个忽然的想法让我找到了问题的所在,现在将代码总结一下,以备自己以后查阅. 首先,Java