CBC模式的3DES加解密(课程设计报告)
创始人
2024-05-16 10:00:55

目录

  • 一、实验内容
  • 二、实验原理
    • 2.1 DES加解密原理
      • 2.1.1 DES加解密的基本原理
      • 2.1.2 DES加解密的关键步骤
    • 2.2 3DES加解密原理
    • 2.3 分组密码CBC加解密模式原理
    • 2.4 填充原理
  • 三、实验过程
    • 3.1 变量说明
      • 3.1.1 主函数变量说明
      • 3.1.2 其他重要变量说明
    • 3.2 函数功能说明
      • 3.2.1主函数说明
      • 3.2.2 其他重要函数说明
    • 3.3 流程图
      • 3.3.1 主函数流程图
      • 3.3.2 其他重要函数流程图
        • 3.3.2.1 part_F函数流程图
        • 3.3.2.2 generateKeys函数流程图
        • 3.3.2.3 encryptDES函数流程图
  • 四、实验结果与截图
  • 五、实验总结
  • 六、代码

一、实验内容

(1)编程实现DES加解密算法,并使用DES加解密算法实现3DES加解密算法
(2)选择一种填充方式,对需要加密的文件进行填充(解密要去掉填充部分)
(3)DES的加解密的工作模式,采用密码分组链接(CBC)模式
(4)读取/写入被加密/解密文件时,采用字节流的形式进行文件读取/写入

二、实验原理

2.1 DES加解密原理

2.1.1 DES加解密的基本原理

  DES的加密过程具体如图1所示。
在这里插入图片描述

图1的加密过程具体可以分为以下几个步骤
1)输入64位明文进行IP置换,分成两个32位分支,左边L0,右边R0
2)右分支:L1 = R0 左分支:引入48位的密钥,R1 = L0 ⊕ F(R0,K1)
3)相同的操作进行16次的运算循环,算出相应的,R1 ~ R16,L0 ~ L16
4)最后在进行IP的逆序置换,将左右两个分支再次合并为64位密文
解密和加密过程是类似的,唯一不同的是秘钥的次序是相反的。如果每一轮的加密秘钥分别是K1、K2、K3…K16,那么解密秘钥就是K16、K15、K14…K1。为每一轮产生秘钥的算法也是循环的。加密是秘钥循环左移,解密是秘钥循环右移。

2.1.2 DES加解密的关键步骤

  通过图1可知DES算法分为两大部分——迭代加密和子密钥生成。
子密钥生成的过程具体如图2所示。
在这里插入图片描述
  图2中的子密钥生成过程可以分为以下几个步骤
1)将64位主钥通过置换选择1变为56 位密钥,它分成左右两个28位半密钥
2)将左、右两个半密钥循环左移指定次数
3)将左右半密钥拼接成56位密钥,再进行置换选择2 ,生成48位的子密钥
4)重复步骤 2、步骤 3 一共 16 次,于是得到了 16 个 48位的子密钥

  迭代加密是进行了16轮完全相同的运算,在运算过程中数据与扩展后秘钥结合。函数F(如图3所示)的输出经过一个异或运算,和左半部分结合形成新的右半部分,原来的右半部分成为新的左半部分。每轮迭代的过程用如下公式表示
Ln = R(n - 1);
Rn = L(n - 1) ⊕ F(Rn-1,kn-1)

在这里插入图片描述
  图3中的轮函数F的具体流程,将一个 32位的块,经过扩展置换变成 48 位,然后与子密钥异或。得到的 48位的结果分为 8 组,每一组是 6位,进行 S 盒替换,输出 4位。把替换结果拼接成32位,进行P 盒置换,得到 32位的结果。其中32位的块与子密钥的混合过程,以及 S 盒提供的强有力的混淆能力,提供了 DES 体系的核心安全性。

2.2 3DES加解密原理

  3DES,该算法的加解密过程分别是对明文/密文数据进行三次DES加密或解密,得到相应的密文或明文。
假设E()和D()分别表示DES的加密和解密函数,M表示明文,C表示密文,那么加解密的公式如下:
加密:C=E(D(E(M,K1),K2),K3),即对明文数据进行加密 --> 解密 --> 加密的过程,最后得到密文数据。
解密:M=D(E(D(C,K3),K2),K1),即对密文数据进行解密 --> 加密 --> 解密的过程,最后得到明文数据。

2.3 分组密码CBC加解密模式原理

  CBC加密过程如图4所示可以分为以下几个步骤
1)首先将明文数据按照8个字节一组进行分组得到M1,M2,…Mn(若数据不是8的整数倍,运用一定的填充原理进行填充)
2)明文M1与初始化向量IV异或后的结果进行DES加密得到密文C1
3)明文M2与密文C1异或后的结果进行DES加密,得到密文C2
4)之后的数据以此类推,得到Cn,将C1,C2,C3…Cn拼接即得到密文

在这里插入图片描述

  CBC解密过程是加密过程的逆过程,如图5所示可以分为以下几个步骤
1)首先将密文按照8个字节一组进行分组得到C1,C2,C3…Cn
2)将密文C1进行解密后与初始化向量IV进行异或得到明文M1
3)将密文C2进行解密后与密文C1进行异或得到明文M2
4)之后依此类推得到Mn,将M1,M2,M3…Mn解填充,拼接得到明文

图 5 CBC解密流程图

2.4 填充原理

  此次加解密的数据是以字节流的形式,64位数据用十六进制表示为16位。
  加密时将明文分为8字节(2位)一组,对明文尾部分类讨论进行填充。
1)最后一个分组不足8字节,则填充为00 00…0X(最后一个字节保存包括最后一个字节在内的所填充的字节数量)
2)最后一个分组正好是8个字节,则填充为00 00…08

  解密时先将密文解密为明文,再对明文的最后一个8字节分组进行解填充。
1)最后一个分组正好是0000…08,则去掉该分组
2)最后一个分组满足最后一个字节是0X,且0X前面有x-1对0,则去掉该组数据分组中的0X和X-1对0

三、实验过程

3.1 变量说明

3.1.1 主函数变量说明

String in_filename; //读取文件的文件路径名
String out_filename; //写入文件的文件路径名
Int model; //用户手动输入的模式值(1 / 2),指定进行加密还是解密
Int fillsize; //记录填充需要的位数
Bitset <64> initV; //保存初始化向量
Bitset <64> pretext; // 保存上一次加密得到的密文,用以CBC模式中的异或
Bitset <64> res; // 保存CBC函数返回的结果,写入文件中的数据

3.1.2 其他重要变量说明

Int initPer[]; //初始置换IP表
Int reverseInitPer[]; //逆初始置换IP-1表
Int permuChoice_1[]; //置换选择1表 64位 -> 56位
Int permuChoice_2[]; //置换选择2表 56位 -> 48位
Int leftShiftbit[16]; //左循环移位表,除了1,2,9,16移动一位,其余都是2
Int extendPer[]; //扩展至换E表 32位 -> 48位
Int sBox[8][4][16]; //S盒
Int pBox[]; //P盒
Bitset <48> keys[16]; //保存生成的子密钥
bitset <64> C, M; //加解密中存储的密文和明文
bitset <64> K1, K2, K3; 3DES加解密中需要的密钥

3.2 函数功能说明

3.2.1主函数说明

1)从文件中读取数据,将加解密的结果写入文件中
2)输出提示语句,实现与用户的交互功能,并确定加密还是解密
3)进行明文的填充和解填充,调用CBC函数进行加解密

3.2.2 其他重要函数说明

1)bitset<32> part_F(bitset<32> R, bitset<48> K)
作用:轮函数F
参数:需要进行运算的字符串R,密钥K
返回:f函数运算后的结果

2)void CShift(int i, bitset<28> &C, bitset<28> &D)
作用:28位密钥循环左移
参数:需要循环左移的左右字符串C, D的引用
返回:无返回值

3)void generateKeys(bitset<64>Key)
作用:生成子密钥
参数:64位的主密钥
返回:无返回值,子密钥存储在全局变量中

4)bitset<64> encryptDES(bitset<64> message, bitset<64>key)
作用:DES加密过程
参数:64位明文和64位的加密密钥
返回:加密后得到的密文

5)bitset<64> decryptDES(bitset<64> cipher, bitset<64>key)
作用:DES解密过程
参数:64位的密文和64位的解密密钥
返回:解密后得到的明文

6)bitset <64> encrypt3DES(bitset <64> M, bitset <64> k1, bitset <64> k2, bitset <64> k3)
作用:3DES加密过程
参数:64位的明文以及加密所需要的密钥K1, K2, K3
返回:加密后得到的密文

7)bitset <64> decrypt3DES(bitset <64> C, bitset <64> k1, bitset <64> k2, bitset <64> k3)
作用:3DES解密过程
参数:64位的密文以及解密所需要的密钥K1, K2, K3

8)string stobit(string str)
作用:将一个字符转化为8位的01字符形式
参数:需要转换的字符数据str
返回:转换后的01字符数据

9)bitset <64> ctoi(string s)
作用:将01字符串存储在在bitset中
参数:需要转换的字符数据s
返回:转换后的bitset数组

10)bitset <64> CBC(bitset <64> data, bitset <64> initV, int model)
作用:CBC模式的加解密过程
参数:需要加解密的数据,初始化向量initV以及判断加密还是解密的标志model
返回:加解密后的结果

3.3 流程图

3.3.1 主函数流程图

    在这里插入图片描述

3.3.2 其他重要函数流程图

3.3.2.1 part_F函数流程图

   在这里插入图片描述

3.3.2.2 generateKeys函数流程图

在这里插入图片描述

3.3.2.3 encryptDES函数流程图

  在这里插入图片描述

四、实验结果与截图

  已根据中间数据验证了轮函数、生成子密钥函数等关键函数的正确性,并且能够正确通过老师给出的测试样例(如图10所示),并且可以实现任意文件的加解密。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

五、实验总结

  这次实验使我受益匪浅。虽然CBC模式下3DES的流程看似十分复杂,但是通过画流程图的梳理,弄清每一步的细节之后,再动手编码就不再感觉那么困难了。在以后的编程中,也应该运用这种方法,将复杂的问题抽象简单化,理清思路再开始编程,不然编码时代码大量冗余并且逻辑不清,容易出现bug并且难以调试。此次实验使我对3DES的加解密流程有了更深入的理解,也增加了我对密码学有了更浓厚的兴趣,在往后的学习中,我会进一步的探索其中的奥秘,十分感谢老师认真的教学和指导。

六、代码

  DES的加解密以及轮函数和子密钥生成等关键步骤已经根据中间数据测试过,编写正确,3DES以及CBC模式还未验证正确性,请合理食用

#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;//初始置换IP
int initPer[] =
{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
};//逆初始置换IP-1
int reverseInitPer[] =
{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
};//置换选择1 64->56
int permuChoice_1[] =
{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
};//置换选择2 56->48
int permuChoice_2[] =
{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
};//左循环移位,除了1,2,9,16,其余都是2
int leftShiftbit[16] =
{1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
};//扩展置换E 32->48
int extendPer[] =
{32, 1, 2, 3, 4, 5,4, 5, 6, 7, 8, 9,8, 9, 10, 11, 12, 13,12, 13, 14, 15, 16, 17,16, 17, 18, 19, 20, 21,20, 21, 22, 23, 24, 25,24, 25, 26, 27, 28, 29,28, 29, 30, 31, 32, 1
};//S盒
int sBox[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{{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10},{3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5},{0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15},{13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}},//S3{{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8},{13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1},{13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7},{1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}},//S4{{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15},{13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9},{10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4},{3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}},//S5{{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9},{14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6},{4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14},{11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}},//S6{{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11},{10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8},{9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6},{4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}},//S7{{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1},{13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6},{1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2},{6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}},//S8{{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7},{1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2},{7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8},{2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}}
};//p盒
int pBox[] =
{16, 7, 20, 21,29, 12, 28, 17,1, 15, 23, 26,5, 18, 31, 10,2, 8, 24, 14,32, 27, 3, 9,19, 13, 30, 6,22, 11, 4, 25
};// 轮函数F的一部分 接受32位数据和48位子密钥,返回32位数据(已验证,正确)
bitset<32> part_F(bitset<32> R, bitset<48> K)
{bitset<48> expandR;//扩展置换 32 -> 48 (已验证,正确)//expandR的第i位为R的第extendPer[i] - 1位for(int i = 0; i < 48; i ++){expandR[i] = R[extendPer[i] - 1];
//        if (i % 6 == 0) cout << " ";
//        cout << expandR[i];}
//    cout << endl;//与k异或 48位 (已验证,正确)expandR = expandR ^ K;//S盒替换 48->32位bitset<32> res;int cnt = 0;for(int i = 0; i < 48; i += 6){//行号为最高位最低位表示的十进制int row = expandR[i] * 2 + expandR[i + 5];//列号为中间四位表示的十进制int col = expandR[i + 1] * 8 + expandR[i + 2] * 4 + expandR[i + 3] * 2 + expandR[i + 4];//选取第i/6个s盒int num = sBox[i / 6][row][col];//拼接bitset<4> tmp = num;for (int j = 3; j >= 0; j --) res[cnt ++] = tmp[j];}
//    for (int i = 0; i < 32; i ++)
//    {
//        if (i % 4 == 0) cout << " ";
//        cout << res[i];
//    }
//    cout << endl;//P置换 32->32bitset<32>tmp = res;for(int i = 0; i < 32; i ++){res[i] = tmp[pBox[i] - 1];
//        if (i % 4 == 0) cout << " ";
//        cout << res[i];}
//    cout << endl;return res;
}//28位密钥左移(已验证,正确)
void CShift(int i, bitset<28> &C, bitset<28> &D)
{//循环左移一位if (leftShiftbit[i] == 1){//C0循环左移一位int t = C[0];for (int j = 0; j < 27; j ++){C[j] = C[j + 1];}C[27] = t;//D0循环左移一位t = D[0];for (int j = 0; j < 27; j ++){D[j] = D[j + 1];}D[27] = t;}else //循环左移两位{//C0循环左移两位int t1 = C[0], t2 = C[1];for (int j = 0; j < 26; j += 2){C[j] = C[j + 2];C[j + 1] = C[j + 3];}C[26] = t1;C[27] = t2;//D0循环左移两位t1 = D[0];t2 = D[1];for (int j = 0; j < 26; j += 2){D[j] = D[j + 2];D[j + 1] = D[j + 3];}D[26] = t1;D[27] = t2;}
}//生成子密钥(已验证,正确)
bitset<48> keys[16]; //生成的子密钥
void generateKeys(bitset<64>Key)
{//置换选择1 64 -> 56 (已验证,正确)bitset<56> nkey;for (int i = 0; i < 56; i ++){nkey[i] = Key[permuChoice_1[i] - 1];
//        if (i % 7 == 0) cout << " ";
//        cout << nkey[i];}
//    cout << endl;//16轮密钥扩展(已验证,正确)for (int i = 0; i < 16; i ++){bitset<28> C, D;//将nkey分为左右两部分for (int j = 0; j < 56; j ++){if (j < 28) C[j] = nkey[j];else D[j - 28] = nkey[j];}//        cout << "C" << i << ":";
//        for (int j = 0; j < 28; j ++)
//        {
//            cout << C[j];
//        }
//        cout << endl;
//        cout << "D" << i << ":";
//        for (int j = 0; j < 28; j ++)
//        {
//            cout << D[j];
//        }
//        cout << endl;CShift(i, C, D);//拼接成新keyfor (int j = 0; j < 56; j ++){if (j < 28) nkey[j] = C[j];else nkey[j] = D[j - 28];}//置换选择2 56 -> 48 (已验证,正确)
//        cout << "k" << i << ':';bitset<48>K;for (int j = 0; j < 48; j ++){K[j] = nkey[permuChoice_2[j] - 1];
//            if (j % 6 == 0) cout << " ";
//            cout << K[j];}
//        cout << endl;keys[i] = K;}
}//DES加密过程 (已验证,正确)
bitset<64> encryptDES(bitset<64> message, bitset<64>key)
{bitset<64> cipher;bitset<32> L, R;//密钥拓展,64位密钥拓展为16 * 48位 (已验证,正确)generateKeys(key);//初始置换IP 64-> 64 (已验证,正确)bitset<64> tmp = message;for (int i = 0; i < 64; i ++){message[i] = tmp[initPer[i] - 1];
//        if (i % 4 == 0) cout << " ";
//        cout << message[i];}
//    cout << endl;//十六轮加密:L0 = R0, R0 = L0 ^ F(R0, k1)for (int i = 0; i < 16; i ++){//先将message分为LR两段for (int j = 0; j < 64; j ++){if (j < 32) L[j] = message[j];else R[j - 32] = message[j];}bitset <32> t = R;R = L ^ part_F(R, keys[i]);L = t;for (int j = 0; j < 64; j ++){if (i == 15){if (j < 32) message[j] = R[j];else message[j] = L[j - 32];}else{if (j < 32) message[j] = L[j];else message[j] = R[j - 32];}
//            if (j % 8 == 0) cout << ' ';
//            cout << message[j];}
//        cout << endl;}//初始逆置换 (已验证,正确)for (int i = 0; i < 64; i ++){cipher[i] = message[reverseInitPer[i] - 1];
//        if (i % 8 == 0) cout << " ";
//        cout << cipher[i];}
//    cout << endl;return cipher;
}//DES解密 (已验证,正确)
bitset<64> decryptDES(bitset<64> cipher, bitset<64>key)
{bitset<64> message;bitset<32> L, R;//密钥拓展,64位密钥拓展为16 * 48位generateKeys(key);//初始逆置换bitset<64> tmp = cipher;for (int i = 0; i < 64; i ++) cipher[reverseInitPer[i] - 1] = tmp[i];//十六轮加密:L0 = R1 ^ F(L1, k1), R0 = L1for (int i = 15; i >= 0; i --){//先将cipher分为LR两段for (int j = 0; j < 64; j ++){if (i == 15){if (j < 32) R[j] = cipher[j];else L[j - 32] = cipher[j];}else{if (j < 32) L[j] = cipher[j];else R[j - 32] = cipher[j];}}bitset <32> t = L;L = R ^ part_F(L, keys[i]);R = t;for (int j = 0; j < 64; j ++){if (j < 32) cipher[j] = L[j];else cipher[j] = R[j - 32];}}//初始置换for (int i = 0; i < 64; i ++) message[initPer[i] - 1] = cipher[i];return message;
}//3DES加密
bitset <64> encrypt3DES(bitset <64> M, bitset <64> k1, bitset <64> k2, bitset <64> k3)
{bitset <64> C;C = encryptDES(M, k1);C = decryptDES(C, k2);C = encryptDES(C, k3);return C;
}//3DES解密
bitset <64> decrypt3DES(bitset <64> C, bitset <64> k1, bitset <64> k2, bitset <64> k3)
{bitset <64> M;M = decryptDES(C, k1);M = encryptDES(M, k2);M = decryptDES(M, k3);return M;
}string stobit(string str) //将每一个字符转换为8为二进制
{unsigned char k = 0x80;int length = str.size();string bit = "";for (int i = 0; i < length; i++){for (int j = 0; j < 8; j++, k >>= 1){//网上所查,原理还在探究//在函数bai中,先将1左移7位,就可以得到二进制值10000000,// 再将此值与一个字符“按位与”,然后判断其值是否为0。不为0就输出1,// 否则就输出0。类似的操作做8次,就可以输出一个字节的8位二进制码了。if (str[i] & k){bit += '1';}else{bit += '0';}}k = 0x80;}return bit;
}//将64位01字符串转换为01数字
bitset <64> ctoi(string s)
{bitset<64> M;for (int i = 0; i < 64; i ++){if (s[i] == '1') M[i] = 1;else M[i] = 0;}return M;
}bitset <64> CBC(bitset <64> data, bitset <64> initV, int model)
{data ^= initV;string key1 = "01519800";string key2 = "12345678";string key3 = "32897592";bitset <64> k1 = ctoi(stobit(key1));bitset <64> k2 = ctoi(stobit(key2));bitset <64> k3 = ctoi(stobit(key3));bitset <64> res;if (model == 1) res = encrypt3DES(data, k1, k2, k3);else res = decrypt3DES(data, k1, k2, k3);return res;
}
int main()
{//目前DES加解密已验证正确string in_filename = "C:\\Users\\Y\\Desktop\\信息安全\\input.txt";string out_filename = "C:\\Users\\Y\\Desktop\\信息安全\\output.txt";ifstream in;in.open(in_filename);ofstream out;out.open(out_filename);string s;in >> s;in.close();puts("加密请按1,解密请按2");int model = 0;while (cin >> model){if (model != 1 && model != 2){puts("输入不正确,请重输");}else{if (model == 1){cout << "您所要加密的文件是" << in_filename <cout << "您所要解密的文件是" << in_filename <if (i == fillsize - 1){int t = fillsize;s += char(t);}else{int t = 0;s += char(t);}}string bitdata = stobit(s);puts("结果如下");string initvector = "12358789";bitset <64> initV = ctoi(stobit(initvector));bitset <64> pretext = initV;for (int i = 0; i < bitdata.size(); i += 64){string t = bitdata.substr(i, 64);bitset <64> tdata = ctoi(t);bitset <64> res = CBC(tdata, pretext, model);pretext = res;cout << res << endl;out << res;}out.close();return 0;
}

相关内容

热门资讯

猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
少数民族的传统节日有哪些 55... 公务员考试常识判断模块考查范围广泛,需要大家在日常多加积累,本文小编总结了中国少数民族的传统节日,希...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
mb什么意思 MB和Mb 相信很多人都还不太清楚手机流量的统计单位,经常听说谁谁流量包月5个G。其实G、GB、KB、M和MB数...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...