当前位置:文档之家› 密码学3DESC++实现

密码学3DESC++实现

JI A N G S U U N I V E R S I T Y 2017-2018学年第1学期密码学课程设计学院名称:计算机科学与通信工程学院班级学号:学生姓名:指导老师:一、实验要求:问题描述:编程实现3DES算法。

从DES原理出发,设计3DES加解密过程;通过编程调试以实现3DES 算法;利用由学生本人的学号姓名等信息组成若干密钥,以及明文样本进行加解密测试;最后作总结。

要求:(1)设计良好的交互界面,如要求用户输入密钥、明文字符串、得到相应的解密字符串等。

(2)程序设计,编写相应程序并调试。

(3)试用验证,记录每次操作过程和系统的结果。

(4)分析相应的问题。

(5)编写课程设计报告。

二、实验过程及分析:算法简介:3DES(或称为Triple DES)是三重数据加密算法(TDEA,Triple Data Encryption Algorithm)块密码的通称。

它相当于是对每个数据块应用三次DES加密算法。

由于计算机运算能力的增强,原版DES密码的密钥长度变得容易被暴力破解;3DES即是设计用来提供一种相对简单的方法,即通过增加DES的密钥长度来避免类似的攻击,而不是设计一种全新的块密码算法。

算法介绍:3DES又称Triple DES,是DES加密算法的一种模式,它使用3条56位的密钥对数据进行三次加密。

数据加密标准(DES)是美国的一种由来已久的加密标准,它使用对称密钥加密法,并于1981年被ANSI组织规范为ANSI X.3.92。

DES使用56位密钥和密码块的方法,而在密码块的方法中,文本被分成64位大小的文本块然后再进行加密。

比起最初的DES,3DES更为安全。

3DES(即Triple DES)是DES向AES过渡的加密算法(1999年,NIST将3-DES指定为过渡的加密标准),加密算法,其具体实现如下:设Ek()和Dk()代表DES算法的加密和解密过程,K代表DES算法使用的密钥,M代表明文,C代表密文,这样:3DES加密过程为:C=Ek3(Dk2(Ek1(M)))3DES解密过程为:M=Dk1(EK2(Dk3(C)))代码实现:我是先用C++将单重DES的算法编译出来,然后再进行三重DES算法,界面是利用MFC编写的一个简单的交互界面,实现对明文的加解密操作,主要的困难是在算法的编写上,在密文的输出形式上花费了许多时间,因为要实现三重加密,而每次明文的输入都必须是字符数组的类型,而第二三次的明文是利用前一次的密文,所以所输出的密文也必须是字符数组类型,有些转换的小问题费了一些功夫;在实现界面的时候CString类型对char类型的数组转换也出了一些问题,不过实验了几个不同的方式还是成功的解决了类型转换的问题,之后就是简单的调用加解密函数进行操作就好了。

实验结果:三、实验代码:头文件des.h:#include<iostream>#include<stdio.h>#include<string.h>#include <bitset>#include<fstream>using namespace std;int IP_Table[64] = { //IP置换矩阵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 };int E_Table[48] = { //扩展矩阵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 };int P_Table[32] = { // P 盒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 };int IPR_Table[64] = { //逆IP置换矩阵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 };int PC1_Table[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 };int PC2_Table[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 };int S_Box[8][4][16] = { //8个S盒三维数组// S114, 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,// S215, 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,// S310, 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,// S47, 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, // S52, 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, // S612, 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, // S74, 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, // S813, 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 };//把CHAR转换为INTstatic void CharToBit(const char input[], int output[], int bits) { int i, j;for (j = 0; j<8; j++) {for (i = 0; i<8; i++) {output[8 * j + 7 - i] = (input[j] >> i) & 1;}}};//把INT转换为CHARstatic void BitToChar(const int intput[], char output[], int bits) { int i, j;for (j = 0; j<8; j++) {for (i = 0; i<8; i++) {output[j] = output[j] * 2 + intput[i + 8 * j];}}};//异或操作static void Xor(int *INA, int *INB, int len) {int i;for (i = 0; i<len; i++) {*(INA + i) = *(INA + i) ^ *(INB + i);}};//初始IP置换,64->64,左右分别32static void IP(const int input[64], int output[64], int table[64]) { int i;for (i = 0; i<64; i++) {output[i] = input[table[i] - 1];//减1操作不可少!!}};//E扩展32->48static void E(const int input[32], int output[48], int table[48]) { int i;for (i = 0; i<48; i++) {output[i] = input[table[i] - 1];}};//P置换,static void P(const int input[32], int output[32], int table[32]) { int i;for (i = 0; i<32; i++) {output[i] = input[table[i] - 1];}};//逆IPstatic void IP_In(const int input[64], int output[64], int table[64]) { int i;for (i = 0; i<64; i++) {output[i] = input[table[i] - 1];}};//PC_1,用于密钥置换static void PC_1(const int input[64], int output[56], int table[56]) { int i;for (i = 0; i<56; i++) {output[i] = input[table[i] - 1];}};//PC_2static void PC_2(const int input[56], int output[48], int table[48]) { int i;for (i = 0; i<48; i++) {output[i] = input[table[i] - 1];}};//S盒压缩static void S(const int input[48], int output[32], int table[8][4][16]) {int i = 0;int j = 0;int INT[8];for (; i<48; i += 6) {INT[j] = table[j][(input[i] << 1) + (input[i + 5])][(input[i + 1] << 3) + (input[i + 2] << 2) + (input[i + 3] << 1) + (input[i + 4])];j++;}for (j = 0; j<8; j++) {for (i = 0; i<4; i++) {output[4 * j + 3 - i] = (INT[j] >> i) & 1;}}};//完成DES算法轮变换,就是f函数的内部实现,就是一个异或而已static void F_func(int input[32], int output[32], int subkey[48]) {int len = 48;int temp[48] = { 0 };int temp_1[32] = { 0 };E(input, temp, E_Table);//32->48Xor(temp, subkey, len);S(temp, temp_1, S_Box);//48->32P(temp_1, output, P_Table);//位数不变};//秘钥循环左移static void RotateL(const int input[28], int output[28], int leftCount) {int i;int len = 28;//因为不是位运算,所以可以不用unsignedfor (i = 0; i<len; i++) {output[i] = input[(i + leftCount) % len];}};//子密钥生成static void subKey_fun(const int input[64], int Subkey[16][48]) {//注意输入和输出的位数,int只存放01,密钥为18位16轮int loop = 1, loop_2 = 2;int i, j;int c[28], d[28];int pc_1[56] = { 0 };int pc_2[16][56] = { 0 };int rotatel_c[16][28] = { 0 };int rotatel_d[16][28] = { 0 };PC_1(input, pc_1, PC1_Table);for (i = 0; i<28; i++) {c[i] = pc_1[i];//Ld[i] = pc_1[i + 28];//R}int leftCount = 0;for (i = 1; i<17; i++) {if (i == 1 || i == 2 || i == 9 || i == 16) {//左移一位leftCount += loop;RotateL(c, rotatel_c[i - 1], leftCount);RotateL(d, rotatel_d[i - 1], leftCount);}else {//左移两位leftCount += loop_2;RotateL(c, rotatel_c[i - 1], leftCount);RotateL(d, rotatel_d[i - 1], leftCount);}}for (i = 0; i<16; i++) {for (j = 0; j<28; j++) {pc_2[i][j] = rotatel_c[i][j];pc_2[i][j + 28] = rotatel_d[i][j];}}for (i = 0; i<16; i++) {PC_2(pc_2[i], Subkey[i], PC2_Table);}};//加密实现static void DES_Efun(char input[8], char key_in[8], int output[64]) {int Ip[64] = { 0 };//存储初始置换后的矩阵int output_1[64] = { 0 };int subkeys[16][48];int chartobit[64] = { 0 };int key[64];int l[17][32], r[17][32];CharToBit(input, chartobit, 8);//转换为64个二进制数IP(chartobit, Ip, IP_Table);//IP初始置换!CharToBit(key_in, key, 8);subKey_fun(key, subkeys);for (int i = 0; i<32; i++) {l[0][i] = Ip[i];r[0][i] = Ip[32 + i];}for (int j = 1; j<16; j++) {//前15轮的操作for (int k = 0; k<32; k++) {l[j][k] = r[j - 1][k];}F_func(r[j - 1], r[j], subkeys[j - 1]);Xor(r[j], l[j - 1], 32);}int t = 0;for (t = 0; t<32; t++) {//最后一轮的操作,合并了将l,r swap r[16][t] = r[15][t];}F_func(r[15], l[16], subkeys[15]);Xor(l[16], l[15], 32);for (t = 0; t<32; t++) {output_1[t] = l[16][t];output_1[32 + t] = r[16][t];}IP_In(output_1, output, IPR_Table);};//解密实现static void DES_Dfun(int input[64], char key_in[8], char output[8]) { int Ip[64] = { 0 };//存储初始置换后的矩阵int output_1[64] = { 0 };int output_2[64] = { 0 };int subkeys[16][48];//int chartobit[64]={0};int key[64];int l[17][32], r[17][32];IP(input, Ip, IP_Table);//IP初始置换CharToBit(key_in, key, 8);subKey_fun(key, subkeys);for (int i = 0; i<32; i++) {l[0][i] = Ip[i];r[0][i] = Ip[32 + i];}for (int j = 1; j<16; j++) {//前15轮的操作for (int k = 0; k<32; k++) {l[j][k] = r[j - 1][k];}F_func(r[j - 1], r[j], subkeys[16 - j]);Xor(r[j], l[j - 1], 32);}int t = 0;for (t = 0; t<32; t++) {//最后一轮的操作r[16][t] = r[15][t];}F_func(r[15], l[16], subkeys[0]);Xor(l[16], l[15], 32);for (t = 0; t<32; t++) {output_1[t] = l[16][t];output_1[32 + t] = r[16][t];}IP_In(output_1, output_2, IPR_Table);BitToChar(output_2, output, 8);};void IntToChar(int input[64], char output[8]){int a = 0x0; //定义一个16进制的二进制数用来存放input的一组四位数for (int i = 0; i < 64; i++){a = a * 2;a = a + input[i];if (i % 8 == 7){if (a<0xa)output[i / 8] = (char)(a + 0x30); //四组十六位二进制数转化为字符类型if (a>0x9)output[i / 8] = (char)(a + 0x40 - 9);a = 0;}}}void change(int in[64], char temp[8]) //天星转换术{bitset<64> m;for (int i = 0; i < 64; i++){m[i] = in[i];}fstream file1;file1.open("d://temp.txt", ios::binary | ios::out);file1.write((char*)&m, sizeof(m));file1.close();file1.open("d://temp.txt", ios::binary | ios::in);file1.getline(temp, 64);file1.close();}int main() {//cout << (char)0x31 << endl;int output[64] = { 0 };char MIN[9] = { 0 };char MI[9] = { 0 };cout << "请输入明文\n";cin >> MIN;cout << "请输入秘钥\n";cin >> MI;DES_Efun(MIN, MI, output);cout << "密文如下\n";char miwen[64];change(output, miwen);cout << miwen << endl;cout << "解密功能\n";DES_Dfun(output, MI, MIN);cout << "明文如下:\n";for (int i = 0; i<8; i++) {cout << MIN[i];}cout << "\n";return 0;}MFC窗口文件tipDlg.cpp :#include "stdafx.h"#include "tip.h"#include "tipDlg.h"#include "afxdialogex.h"#include"des.h"#include <string>#ifdef _DEBUG#define new DEBUG_NEW#endif// 用于应用程序“关于”菜单项的CAboutDlg 对话框class CAboutDlg : public CDialogEx{public:CAboutDlg();// 对话框数据#ifdef AFX_DESIGN_TIMEenum { IDD = IDD_ABOUTBOX };#endifprotected:virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持// 实现protected:DECLARE_MESSAGE_MAP()};CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX){}void CAboutDlg::DoDataExchange(CDataExchange* pDX){CDialogEx::DoDataExchange(pDX);}BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)END_MESSAGE_MAP()// CtipDlg 对话框CtipDlg::CtipDlg(CWnd* pParent /*=NULL*/): CDialog(IDD_TIP_DIALOG, pParent), a(0), b(0), c(0), ming(_T("")), mi(_T("")), miwen1(_T("")), 解密明文(_T("")), jiemimw(_T("")), jmmw(_T("")), mi2(_T("")), mi3(_T("")){m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);}void CtipDlg::DoDataExchange(CDataExchange* pDX){CDialog::DoDataExchange(pDX);DDX_Text(pDX, IDC_EDIT4, ming);DDX_Text(pDX, IDC_EDIT6, mi);DDX_Text(pDX, IDC_EDIT7, miwen1);DDX_Text(pDX, IDC_EDIT1, jmmw);DDX_Text(pDX, IDC_EDIT2, mi2);DDX_Text(pDX, IDC_EDIT3, mi3);}BEGIN_MESSAGE_MAP(CtipDlg, CDialog)ON_WM_SYSCOMMAND()ON_WM_PAINT()ON_WM_QUERYDRAGICON()ON_BN_CLICKED(IDC_BUTTON2, &CtipDlg::OnBnClickedButton2) ON_EN_CHANGE(IDC_EDIT4, &CtipDlg::OnEnChangeEdit4)ON_EN_CHANGE(IDC_EDIT7, &CtipDlg::OnEnChangeEdit7)ON_BN_CLICKED(IDC_BUTTON1, &CtipDlg::OnBnClickedButton1) END_MESSAGE_MAP()// CtipDlg 消息处理程序BOOL CtipDlg::OnInitDialog(){CDialog::OnInitDialog();// 将“关于...”菜单项添加到系统菜单中。

相关主题