DES加密与解密C实现+实验报告
- 格式:docx
- 大小:178.95 KB
- 文档页数:31
DES加密算法的简单实现实验报告一、实验目的本实验的主要目的是对DES加密算法进行简单的实现,并通过实际运行案例来验证算法的正确性和可靠性。
通过该实验可以让学生进一步了解DES算法的工作原理和加密过程,并培养学生对算法实现和数据处理的能力。
二、实验原理DES(Data Encryption Standard,数据加密标准)是一种对称密钥加密算法,它是美国联邦政府采用的一种加密标准。
DES算法使用了一个共享的对称密钥(也称为密钥),用于加密和解密数据。
它采用了分组密码的方式,在进行加密和解密操作时,需要将数据分成固定长度的数据块,并使用密钥对数据进行加密和解密。
DES算法主要由四个步骤组成:初始置换(Initial Permutation),轮函数(Round Function),轮置换(Round Permutation)和最终置换(Final Permutation)。
其中初始置换和最终置换是固定的置换过程,用于改变数据的顺序和排列方式。
轮函数是DES算法的核心部分,它使用了密钥和数据块作为输入,并生成一个与数据块长度相同的输出结果。
轮置换将轮函数的输出结果与前一轮的结果进行异或操作,从而改变数据的排列方式。
通过多轮的迭代运算,DES算法可以通过一个给定的密钥对数据进行高强度的加密和解密操作。
三、实验步骤2.初始置换:将输入数据按照一定的规则重新排列,生成一个新的数据块。
初始置换的规则通过查表的方式给出,我们可以根据规则生成初始置换的代码。
3.轮函数:轮函数是DES算法的核心部分,它使用轮密钥和数据块作为输入,并生成一个与数据块长度相同的输出结果。
在实际的算法设计和实现中,可以使用混合逻辑电路等方式来实现轮函数。
4.轮置换:轮置换将轮函数的输出结果与前一轮的结果进行异或操作,从而改变数据的排列方式。
轮置换的规则也可以通过查表的方式给出。
5.最终置换:最终置换与初始置换类似,将最后一轮的结果重新排列,生成最终的加密结果。
一、实验背景随着信息技术的飞速发展,信息安全问题日益突出。
密码学作为保障信息安全的核心技术,在数据加密、身份认证、数字签名等领域发挥着重要作用。
为了加深对密码学原理的理解,提高实际应用能力,我们开展了本次密码学案例实验。
二、实验目的1. 掌握DES加密算法的基本原理和操作步骤。
2. 熟悉RSA加密算法的原理和应用。
3. 学习数字签名技术的应用。
4. 培养动手实践能力,提高解决实际问题的能力。
三、实验内容1. DES加密算法(1)实验目的:了解DES加密算法的基本原理,掌握DES加密和解密过程。
(2)实验内容:① 设计一个简单的DES加密程序,实现明文到密文的转换。
② 设计一个简单的DES解密程序,实现密文到明文的转换。
(3)实验步骤:① 编写DES加密程序,输入明文和密钥,输出密文。
② 编写DES解密程序,输入密文和密钥,输出明文。
2. RSA加密算法(1)实验目的:了解RSA加密算法的基本原理,掌握RSA加密和解密过程。
(2)实验内容:① 设计一个简单的RSA加密程序,实现明文到密文的转换。
② 设计一个简单的RSA解密程序,实现密文到明文的转换。
(3)实验步骤:① 编写RSA加密程序,输入明文和密钥对,输出密文。
② 编写RSA解密程序,输入密文和私钥,输出明文。
3. 数字签名技术(1)实验目的:了解数字签名技术的基本原理,掌握数字签名的生成和验证过程。
(2)实验内容:① 设计一个简单的数字签名程序,实现签名生成和验证。
(3)实验步骤:① 编写数字签名程序,输入明文、私钥和签名算法,输出签名。
② 编写数字签名验证程序,输入明文、公钥和签名,验证签名是否正确。
四、实验结果与分析1. DES加密算法实验结果通过编写DES加密和解密程序,成功实现了明文到密文和密文到明文的转换。
实验结果表明,DES加密算法在保证数据安全的同时,具有较高的效率。
2. RSA加密算法实验结果通过编写RSA加密和解密程序,成功实现了明文到密文和密文到明文的转换。
【精品】DES算法实验报告一、理论部分DES算法是一种对称加密算法,也是目前广泛应用的加密算法之一。
DES算法使用的是分组加密的思想,将明文数据分成一定长度的数据块,按照一定的算法进行加密,得到密文数据。
DES算法中的关键是密钥,只有持有正确密钥的人才能解密。
DES算法的密钥长度为64位,但由于存在弱密钥的问题,使用时需要特别注意。
DES算法的加密过程包括以下几个步骤:1、密钥的生成和处理:DES算法的密钥长度为64位,但由于存在弱密钥的问题,使用时需要使用程序进行特殊处理,以确保生成的密钥不为弱密钥。
2、初始置换(IP):将明文数据按照一定的规则进行置换,得到置换后的数据。
3、分组:将置换后的明文数据分成左半部分和右半部分。
4、轮函数(f函数):将右半部分进行扩展置换、异或运算、S盒代替、置换等操作,得到一个新的右半部分。
5、轮秘钥生成:生成本轮加密所需要的秘钥。
6、异或运算:将左半部分和右半部分进行异或运算,得到一个新的左半部分。
7、左右交换:将左右部分进行交换。
以上步骤循环执行16次,直到得到最终的密文数据。
二、实验部分本次实验使用C语言实现了DES算法的加密和解密过程。
具体实现过程包括以下几个部分:1、密钥的生成:使用DES算法生成64位密钥,其中包括了对弱密钥的处理。
2、置换:使用DES算法中的IP置换和IP逆置换进行数据置换。
3、轮函数:使用DES算法中的f函数进行一轮加密操作。
5、加密:循环执行16轮加密操作,得到密文数据。
以上实现过程全部基于DES算法的规范。
三、结果分析1、速度慢:由于DES算法采用的是分组加密的思想,需要执行多次操作才能得到最终结果。
因此本次实验的加密和解密速度相对较慢。
2、代码简单:本次实验的代码相对简单,只需要用到一些基本数据结构和算法即可实现DES算法的加密和解密过程。
但需要注意的是,由于DES算法本身的复杂性,代码实现中需要注意细节和边界问题。
四、总结本次实验使用C语言实现了DES算法的加密和解密过程,通过实验得到了一些结果。
DES加密解密实验报告实验报告题目:DES加密解密实验一、实验目的1.了解DES加密算法的工作原理。
2. 学习使用Python编程语言实现DES加密算法。
3.掌握DES加密算法的应用方法。
二、实验原理DES(Data Encryption Standard)是一种用于加密的对称密钥算法,其密钥长度为64位,分为加密过程和解密过程。
1.加密过程(1)初始置换IP:将64位明文分成左右两部分,分别为L0和R0,进行初始置换IP操作。
(2)子密钥生成:按照规则生成16个子密钥,每个子密钥长度为48位。
(3)迭代加密:通过16轮迭代加密运算,得到最终的密文。
每轮迭代加密包括扩展置换、异或运算、S盒替代、P置换和交换操作。
(4)逆初始置换:将最终的密文分成左右两部分,进行逆初始置换操作,得到最终加密结果。
2.解密过程解密过程与加密过程类似,但是子密钥的使用顺序与加密过程相反。
三、实验材料与方法材料:电脑、Python编程环境、DES加密解密算法代码。
方法:1. 在Python编程环境中导入DES加密解密算法库。
2.输入明文和密钥。
3.调用DES加密函数,得到密文。
4.调用DES解密函数,得到解密结果。
5.输出密文和解密结果。
四、实验步骤1.导入DES加密解密算法库:```pythonfrom Crypto.Cipher import DES```2.输入明文和密钥:```pythonplaintext = "Hello World"key = "ThisIsKey"```3.创建DES加密对象:```pythoncipher = DES.new(key.encode(, DES.MODE_ECB) ```。
des密码算法实验c语言以下是一个使用C语言实现DES密码算法的简单实验示例:```c#include <stdio.h>#include <stdlib.h>#include <string.h>#include <openssl/des.h>int main() {// 输入明文char plaintext[8] = "12345678";// 初始化DES密钥DES_cblock key = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF};DES_key_schedule keysched;DES_set_key_unchecked(&key, &keysched);// 加密unsigned char ciphertext[8];DES_cblock ivec = {0}; // 初始化向量DES_ncbc_encrypt(plaintext, ciphertext, sizeof(plaintext),&keysched, &ivec, DES_ENCRYPT);// 输出密文printf("Ciphertext: ");for (int i = 0; i < sizeof(plaintext); i++) {printf("%02X", ciphertext[i]);}printf("\n");// 解密unsigned char decryptedtext[8];memset(ivec, 0, sizeof(ivec)); // 重置初始化向量DES_ncbc_encrypt(ciphertext, decryptedtext, sizeof(plaintext), &keysched, &ivec, DES_DECRYPT);// 输出明文printf("Plaintext: ");for (int i = 0; i < sizeof(plaintext); i++) {printf("%c", decryptedtext[i]);}printf("\n");return 0;}```在这个实验中,我们使用了OpenSSL库中的DES函数来实现DES 密码算法。
xx工程大学实验报告(2015-2016学年第一学期)报告题目: DES加密算法课程名称:密码学B任课教员:专业:学号:姓名:二O一六年一月十八日一、课程概述目的:培养学员的编程能力,理解算法原理。
要求:给出DES算法的软件实现,测试DES的加密速度。
二、设计思路使用C++语言进行编程,简化了输入输出语句。
预处理时加入了iostream包。
使用了std名字空间。
加密时程序输入的明文是8个ascii码,生成一个16个16进制数的密文。
脱密时程序输入的密文是16个16进制数,生成一个8个ascii码的明文。
加脱密所用密钥均由16个16进制数组成。
其中16进制数全部使用大写字母。
程序中大量使用了的布尔数组,一个bool型变量只占用一位存储空间,比int型、char型变量要小的多。
这降低了程序的空间复杂度。
三、采取的方案本程序是将一个由8个ascii码组成的明文分组加密,生成一个由16个16进制数组成的密文。
或将一个由16个16进制数组成的密文进行脱密,生成一个由8个ascii码组成的明文。
所用密钥由16个16进制数组成。
本实验按照输入数据及初始置换、16圈迭代、子密钥生成和逆初始置换及输出数据四个步骤实现加密算法设计。
1、输入数据及初始置换本程序首先会提示用户输入加密脱密识别码,加密输入1,脱密输入0,将此识别码存入整形变量o。
根据o的不同值,提示用户输入8个字符(加密)或16个16进制数(脱密)。
输入的明文或密文转化为二进制数后储存到布尔型数组m[65]中。
初始置换通过函数IP完成,函数输入为原始明文m,函数将输出结果保存到布尔型数组mip[65]中。
函数思想为查表,含有一个整形变量数组ip[64],保存初始变换表IP。
将mip的第i位赋值为m的第ip[i]位。
2、子密钥生成输入16个16进制数的密钥后,将密钥保存在一个16位字符数组c中,通过ToEr函数将之变为二进制数。
ToEr函数输入为字符数组,通过switch语句逐个检查字符数组的每一位,将对应的四位二进制数存在64位布尔数组k中。
DES_加密解密算法C实现--实验报告des算法实验.....1实验一1、实验题目利用C/C++编程实现DES加密算法或MD5加密算法。
我选择的是用C++语言实现DES的加密算法。
2、实验目的通过编码实现DES算法或MD5算法,深入掌握算法的加密原理,理解其实际应用价值,同时要求用C/C++语言实现该算法,让我们从底层开始熟悉该算法的实现过程3、实验环境操作系统:WIN7旗舰版开发工具:VisualStudio2022旗舰版开发语言:C++4、实验原理DES加密流程2如上图所示为DES的加密流程,其中主要包含初始置换,压缩换位1,压缩换位2,扩展置换,S盒置换,异或运算、终结置换等过程。
初始置换是按照初始置换表将64位明文重新排列次序扩展置换是将原32为数据扩展为48位数据,它主要由三个目的:1、产生与子密钥相同的长度2、提供更长的结果,使其在加密过程中可以被压缩3、产生雪崩效应,使得输入的一位将影响两个替换S盒置换是DES算法中最核心的容,在DES中,只有S盒置换是非线性的,它比DES中其他任何一步都提供更好的平安性终结置换与初始置换相对应,它们都不影响DES的平安性,主要目的是为了更容易将明文与密文数据一字节大小放入DES的f算法中DES解密流程与加密流程根本相同,只不过在进行16轮迭代元算时,将子密钥生成的K的次序倒过来进行迭代运算5、实验过程记录在对DES算法有了清晰的认识后,编码过程中我将其分为几个关键局部分别进行编码,最后将整个过程按顺序执行,即可完成DES的加密,代码的主要几个函数如下://Byte转为BitByteToBit(ElemTypech,ElemTypebit[8])//Bit转为ByteBitToByte(ElemTypebit[8],ElemType&ch)//初始置换InitialE某(ElemTypeInorder[64],ElemTypeDisorder[64])//终结置换AntiE某(ElemTypeDisorder[64])//扩展置换E某pandE某(ElemTypeRightMsg[32],ElemTypeE某pandMsg[48])//16轮迭代加密MoveLeft(ElemTypeC[28],ElemTypeD[28],ElemTypeL0[32],ElemType R0[32])3//16轮迭代解密mMoveLeft(ElemTypeC[28],ElemTypeD[28],ElemTypeL0[32],ElemTyp eR0[32])//生成48位子密钥GetCD48(ElemTypeC[28],ElemTypeD[28],ElemTypeSecret[48])//48位明文与子密钥进行异或运算某OR(ElemTypeE某pandMsg[48],ElemTypeSecret[48],ElemTypeResult[48])//S盒四位输出getSOut(ElemTypeResult[48],ElemTypeSout[32])//直接置换DirE某change(ElemTypeSout[32],ElemTypeDirOut[32])//Li与Ri 进行抑或运算某ORLR(ElemTypeDirOut[32],ElemTypeLeft[32],ElemTypeResult[32])函数执行次序和调用关系关系如下:6.源代码//DES.cpp:定义控制台应用程序的入口点。
DES实验报告一、实验目的实现DES算法。
二、实验过程按照DES的算法流程设计,具体实施详见附件。
三、使用方法首先输入密钥,八位ASCII长,否则报错。
然后输入读入文件名和写入文件名,必须以ASCII编码,否则不能使用。
四、实验结果将自身cpp文件进行加密解密,前后文件完全一样。
见文件附录源代码:// 滴一欸死.cpp : 定义控制台应用程序的入口点。
//#include"stdafx.h"#include<stdio.h>#include<stdlib.h>#include<string.h>#include<malloc.h>#include<conio.h>#include"table.h"/* Constant */#define ENCRYPT_LENGTH8 //length of each unit in encryption#define DECIPHER_LENGTH 4 //length of each unit in decipher#define MAX320xFFFFFFFF //mask of 32 bits/* Declaration */typedefunsignedlonglong bit64;typedefunsignedlonglong bit56;typedefunsignedlonglong bit48;typedefunsignedint bit32;typedefunsignedint bit28;/* File stream */FILE *fin, *fout;/* For debug */inlinevoid printBite(bit64num){while (num){printf("%d", num % 2);num>>= 1;}printf("\n");}/* Transfer from char to bit in Encrtption */ inline bit64 ToBit(char *in // source string);/* Transfer from char to bit in Deciphtering */ inline bit64 DeToBit(char *in // source string);/* Transfer from bit to char */inlinevoid ToBite(char *out, // out stringbit64 num // source bits);/* Permutation */inline bit64 substitute(bit64 num, // source bitsconstint *table, // Permutation tablesize_t len // bits length);/* Bit recycle loop to left */inline bit28 MoveLeft(bit28 key, // source bitsint len // bits length);/* Bit recycle loop to right */inline bit28 MoveRight(bit28 key, // source bitsint len // bits length);/* Divide bits into two parts */inlinevoid divide(bit64 num, // source bitsint len, // length of each bitsbit32 *L, // left out bitsbit32 *R // right out bits);/* S box */inline bit32 SChange(bit48 num // source bits);/* F box */inline bit32 FChange(bit32 num, // source bitsbit48 key // secret key);/* Key initialization */inlinevoid SetKey(char *in // string of key);/* Enryption */inlinevoid DES(char *message // messages to be encrypted);/* Deciphering */inlinevoid Decipher(char *message // messages to be deciphered );/* Initialization */inlinevoid init();int main(){init();system("pause");return 0;}/* Initialization */inlinevoid init(){/* Set secret key */printf("Please input your secret key (8 digits):\n");char key[10000];scanf("%s", key);if (strlen(key) != 8){printf("ERROR Key\n");return;}SetKey(key);/* Set mode Encryption or Deciphering */printf("Please input the mode (\"E\" for Encrypt, \"D\" for Decipher):\n");void (*p)(char*);int delta = 8;switch (getch()){case'E': p = DES; delta = 8; break;case'D': p = Decipher; delta = 16; break;default: printf("ERROR!\n"); return;}/* Load file */printf("Please input the path of the in file:\n");char message[10000], in[100], out[100];scanf("%s", in);printf("Please input the path of the out file:\n");scanf("%s", out);fin = freopen(in, "r", stdin);fout = freopen(out, "w", stdout);/* If success */if (!fin || !fout){printf("Error open file!\n");return;}/* Read file */while (gets_s(message)){for (int i = 0; i < strlen(message); i += delta){p(message + i);}printf("\n");}/* Close stream */fclose(stdin);fclose(stdout);fclose(fin);fclose(fout);}/* Transfer from char to bit in Encrtption */inline bit64 ToBit(char *in){/* If valid */if (!in){return 0;}/* Copy char* */char temp[8];memset(temp, ' ', 8 * sizeof(char));for (int i = 0; i < strlen(in) && i <ENCRYPT_LENGTH; i++) {temp[i] = in[i];}/* Transfer to bit */bit64 key = 0x0;for (int i = 0; i <ENCRYPT_LENGTH; i++){key |= ((bit64)temp[i] << (ENCRYPT_LENGTH * i));}return key;}/* Transfer from char to bit in Deciphtering */inline bit64 DeToBit(char *in){/* If valid */if (!in){return 0;}/* Copy char* */char temp[64 / DECIPHER_LENGTH];memset(temp, ' ', 8 * sizeof(char));for (int i = 0; i < 64 / DECIPHER_LENGTH; i++){if (in[i] >= 'A'){temp[i] = in[i] - '7';}else{if (in[i] >= '0'){temp[i] = in[i] - '0';}}}/* Transfer to bit */bit64 key = 0x0;for (int i = 0; i < 64 / DECIPHER_LENGTH; i++){key |= ((bit64)temp[i] << (DECIPHER_LENGTH * i));}return key;}/* Transfer from bit to char */inlinevoid ToBite(char *out, bit64num){if (strlen(out) <= ENCRYPT_LENGTH){out = (char*)malloc(sizeof(char) * (ENCRYPT_LENGTH + 1));}memset(out, 0, sizeof(char) * (ENCRYPT_LENGTH + 1));for (int i = 0; i <ENCRYPT_LENGTH; i++){out[i] = num& 0xFF;}}/* Permutation */inline bit64 substitute(bit64num, constint *table, size_t len) {bit64 out = 0;/* Calculation */for (int i = 0; i <len; i++){out |= ((bit64)((num>> (table[i] - 1)) & 1) << i);}return out;}/* Bit recycle loop to left */inline bit28 MoveLeft(bit28key, int len){bit28 temp = 0;temp = key<< (28 - len); // right bitskey = key>>len; // left bitskey |= temp; // comparekey&= 0x0FFFFFFF; // delete highest four bits return key;}/* Bit recycle loop to right */inline bit28 MoveRight(bit28key, int len){bit28 temp = 0;temp = key>> (28 - len); // right bitskey = key<<len; // left bitskey |= temp; // comparereturn key;}/* Divide bits into two parts */inlinevoid divide(bit64num, int len, bit32 *L, bit32 *R){*L = *R = 0;*L = num&MAX32;*R = num&MAX32;}/* S box */inline bit32 SChange(bit48num){bit32 key = 0;for (int i = 0; i < 8; i++){bit32 x, y;x = (num>> 1) & 0x0F; // the middle four bitsy = (((num>> 5) & 1) << 1) | (num& 1); // the first and the last bitskey |= (S[i][y][x] << (i * 4)); // permutatenum>>= 6; // change to next }return key;}/* F box */inline bit32 FChange(bit32num, bit48key){bit48 temp = substitute(num, E, sizeof(E) / sizeof(E[0]));temp ^= key;num = SChange(temp);return substitute(num, P, sizeof(P) / sizeof(P[0]));}/* Key initialization */inlinevoid SetKey(char *in){bit64 key = ToBit(in);bit28 C, D;key = substitute(key, PC1, sizeof(PC1) / sizeof(PC1[0]));divide(key, 28, &C, &D);for (int i = 0; i < 16; i++){C = MoveLeft(C, Move[i]);D = MoveLeft(D, Move[i]);key = (bit64)C | ((bit64)D << 28);SubKey[i] = substitute(key, PC2, 48);}}/* Enryption */inlinevoid DES(char *message){bit64 BitMes = substitute(ToBit(message), IP, sizeof(IP) / sizeof(IP[0]));bit32 L, R, temp;divide(BitMes, 32, &L, &R);/* 16 rounds */for (int i = 0; i < 16; i++){temp = R;R = FChange(R, SubKey[i]);R ^= L;L = temp;}BitMes = (bit64)L | ((bit64)R << 32);BitMes = substitute(BitMes, IPR, sizeof(IPR) / sizeof(IPR[0]));/* print encrypted message */for (int i = 0; i < 16; i++){char temp = (0xF & (BitMes >> (i * 4)));temp += (temp > 9 ? '7' : '0');printf("%c", temp);}}/* Deciphering */inlinevoid Decipher(char *message){bit64 BitMes = substitute(DeToBit(message), IP, sizeof(IP) / sizeof(IP[0]));bit32 L, R, temp;divide(BitMes, 32, &L, &R);/* 16 rounds */for (int i = 15; i >= 0; i--){temp = L;L = FChange(L, SubKey[i]);L ^= R;R = temp;}BitMes = (bit64)L | ((bit64)R << 32);BitMes = substitute(BitMes, IPR, sizeof(IPR) / sizeof(IPR[0]));/* print deciphered messages */for (int i = 0; i < 8; i++){printf("%c", (0xFF & (BitMes >> (i * 8))));}}table.h文件#pragmaonce/* IP permutation for plaintext */constint 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};/* IPR permutation to print */constint IPR[64] = {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};/*--------------------------- premutation ----------------------------*//* the expansion permutation */staticint E[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};/* Compression permutation */staticint PC1[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};/* Number of key bits shifted per round */staticint Move[16] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 };/* Compression permutation */staticint PC2[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,34,33,48,44,49,39,56,34,53,46,42,50,36,29,32};/*------------- F function ---------------*//* S boxes permutation */staticint S[8][4][16] = {//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, 0, 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, 0, 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 };/* P boxes permutation */staticint P[32] = {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 };/* 16 subkey undefined */staticunsignedlonglong SubKey[16];。
xx工程大学实验报告(2015-2016学年第一学期)报告题目:DES加密算法课程名称:密码学B任课教员:专业:学号:姓名:二O一六年一月十八日一、课程概述目的:培养学员的编程能力,理解算法原理。
要求:给出DES算法的软件实现,测试DES的加密速度。
二、设计思路使用C++语言进行编程,简化了输入输出语句。
预处理时加入了iostream包。
使用了std名字空间。
加密时程序输入的明文是8个ascii码,生成一个16个16进制数的密文。
脱密时程序输入的密文是16个16进制数,生成一个8个ascii码的明文。
加脱密所用密钥均由16个16进制数组成。
其中16进制数全部使用大写字母。
程序中大量使用了的布尔数组,一个bool型变量只占用一位存储空间,比int型、char型变量要小的多。
这降低了程序的空间复杂度。
三、采取的方案本程序是将一个由8个ascii码组成的明文分组加密,生成一个由16个16进制数组成的密文。
或将一个由16个16进制数组成的密文进行脱密,生成一个由8个ascii 码组成的明文。
所用密钥由16个16进制数组成。
本实验按照输入数据及初始置换、16圈迭代、子密钥生成和逆初始置换及输出数据四个步骤实现加密算法设计。
1、输入数据及初始置换本程序首先会提示用户输入加密脱密识别码,加密输入1,脱密输入0,将此识别码存入整形变量o。
根据o的不同值,提示用户输入8个字符(加密)或16个16进制数(脱密)。
输入的明文或密文转化为二进制数后储存到布尔型数组m[65]中。
初始置换通过函数IP完成,函数输入为原始明文m,函数将输出结果保存到布尔型数组mip[65]中。
函数思想为查表,含有一个整形变量数组ip[64],保存初始变换表IP。
将mip的第i位赋值为m的第ip[i]位。
2、子密钥生成输入16个16进制数的密钥后,将密钥保存在一个16位字符数组c中,通过ToEr函数将之变为二进制数。
ToEr函数输入为字符数组,通过switch语句逐个检查字符数组的每一位,将对应的四位二进制数存在64位布尔数组k中。
实验⼀:C语⾔实现DES加解密算法计算程序执⾏10万次需要的时间:总共需要175秒加解密⼀次的时间⼩于:0.00175秒纯计算加解密的时间会更短去除IO操作后的时间也就是说加解密⼀次的时间为0.07毫秒1/*-------------------------------------------------------2Data Encryption Standard 56位密钥加密64位数据3--------------------------------------------------------*/4 #include <stdlib.h>5 #include <stdio.h>6 #include <time.h>7 #include "bool.h"// 位处理8 #include "tables.h"910void BitsCopy(bool *DatOut, bool *DatIn, int Len); // 数组复制1112void ByteToBit(bool *DatOut, char *DatIn, int Num); // 字节到位13void BitToByte(char *DatOut, bool *DatIn, int Num); // 位到字节1415void BitToHex(char *DatOut, bool *DatIn, int Num); // ⼆进制到⼗六进制 64位 to 4*16字符16void HexToBit(bool *DatOut, char *DatIn, int Num); // ⼗六进制到⼆进制1718void TablePermute(bool *DatOut, bool *DatIn, const char *Table, int Num); // 位表置换函数19void LoopMove(bool *DatIn, int Len, int Num); // 循环左移 Len长度 Num移动位数20void Xor(bool *DatA, bool *DatB, int Num); // 异或函数2122void S_Change(bool DatOut[32], bool DatIn[48]); // S盒变换23void F_Change(bool DatIn[32], bool DatKi[48]); // F函数2425void SetKey(char KeyIn[8]); // 设置密钥26void PlayDes(char MesOut[8], char MesIn[8]); // 执⾏DES加密27void KickDes(char MesOut[8], char MesIn[8]); // 执⾏DES解密28293031int main()32 {33 clock_t aaa, bbb;34int jjj = 0;35 aaa = time(NULL);36while (jjj <100000)37 {38int i = 0;39char MesHex[16] = { 0 }; // 16个字符数组⽤于存放 64位16进制的密⽂40char MyKey[8] = { 0 }; // 初始密钥 8字节*841char YourKey[8] = { 0 }; // 输⼊的解密密钥 8字节*842char MyMessage[8] = { 0 }; // 初始明⽂4344/*-----------------------------------------------*/4546 printf("Welcome! Please input your Message(64 bit):\n");47//gets(MyMessage); // 明⽂48 MyMessage[0] = '1';49 MyMessage[1] = '2';50 MyMessage[2] = '3';51 MyMessage[3] = '4';52 MyMessage[4] = '5';53 MyMessage[5] = '6';54 MyMessage[6] = '7';55 MyMessage[7] = '8';56//MyMessage[0] = '\0';57 printf("Please input your Secret Key:\n");58 MyKey[0] = '1'; // 密钥59 MyKey[1] = '2';60 MyKey[2] = '3';61 MyKey[3] = '4';62 MyKey[4] = '5';63 MyKey[5] = '6';64 MyKey[6] = '7';65 MyKey[7] = '8';66//MyKey[8] = '\0';67while (MyKey[i] != '\0') // 计算密钥长度68 {69 i++;70 }71/*72 while (i != 8) // 不是8 提⽰错误73 {74 printf("Please input a correct Secret Key!\n");75 gets(MyKey);76 i = 0;77 while (MyKey[i] != '\0') // 再次检测78 {79 i++;80 }81 }*/8283 SetKey(MyKey); // 设置密钥得到⼦密钥Ki8485 PlayDes(MesHex, MyMessage); // 执⾏DES加密8687 printf("Your Message is Encrypted!:\n"); // 信息已加密88for (i = 0; i < 16; i++)89 {90 printf("%c ", MesHex[i]);91 }92 printf("\n\n");9394 printf("Please input your Secret Key to Deciphering:\n"); // 请输⼊密钥以解密 95//gets(YourKey); // 得到密钥96 YourKey[0] = '1';97 YourKey[1] = '2';98 YourKey[2] = '3';99 YourKey[3] = '4';100 YourKey[4] = '5';101 YourKey[5] = '6';102 YourKey[6] = '7';103 YourKey[7] = '8';104//YourKey[8] = '\0';105 SetKey(YourKey); // 设置密钥106107 KickDes(MyMessage, MesHex); // 解密输出到MyMessage 108109 printf("Deciphering Over !!:\n"); // 解密结束110for (i = 0; i < 8; i++)111 {112 printf("%c ", MyMessage[i]);113 }114 printf("\n\n");115116 jjj++;117 }118 bbb = time(NULL);119 printf("bbb-aaa= %f",(double)(bbb - aaa));120 system("pause");121/*------------------------------------------------*/122 }123124/*-------------------------------125把DatIn开始的长度位Len位的⼆进制126复制到DatOut后127--------------------------------*/128void BitsCopy(bool *DatOut, bool *DatIn, int Len) // 数组复制 OK129 {130int i = 0;131for (i = 0; i<Len; i++)132 {133 DatOut[i] = DatIn[i];134 }135 }136137/*-------------------------------138字节转换成位函数139每8次换⼀个字节每次向右移⼀位140和1与取最后⼀位共64位141--------------------------------*/142void ByteToBit(bool *DatOut, char *DatIn, int Num) // OK143 {144int i = 0;145for (i = 0; i<Num; i++)146 {147 DatOut[i] = (DatIn[i / 8] >> (i % 8)) & 0x01;148 }149 }150151/*-------------------------------152位转换成字节函数153字节数组每8次移⼀位154位每次向左移与上⼀次或155---------------------------------*/156void BitToByte(char *DatOut, bool *DatIn, int Num) // OK157 {158int i = 0;159for (i = 0; i<(Num / 8); i++)160 {161 DatOut[i] = 0;162 }163for (i = 0; i<Num; i++)164 {165 DatOut[i / 8] |= DatIn[i] << (i % 8);166 }167 }168169170/*----------------------------------171⼆进制密⽂转换为⼗六进制172需要16个字符表⽰173-----------------------------------*/174void BitToHex(char *DatOut, bool *DatIn, int Num)175 {176int i = 0;177for (i = 0; i<Num / 4; i++)178 {179 DatOut[i] = 0;180 }181for (i = 0; i<Num / 4; i++)182 {183 DatOut[i] = DatIn[i * 4] + (DatIn[i * 4 + 1] << 1)184 + (DatIn[i * 4 + 2] << 2) + (DatIn[i * 4 + 3] << 3);185if ((DatOut[i] % 16)>9)186 {187 DatOut[i] = DatOut[i] % 16 + '7'; // 余数⼤于9时处理 10-15 to A-F 188 } // 输出字符189else190 {191 DatOut[i] = DatOut[i] % 16 + '0'; // 输出字符192 }193 }194195 }196197/*---------------------------------------------198⼗六进制字符转⼆进制199----------------------------------------------*/200void HexToBit(bool *DatOut, char *DatIn, int Num)201 {202int i = 0; // 字符型输⼊203for (i = 0; i<Num; i++)204 {205if ((DatIn[i / 4])>'9') // ⼤于9206 {207 DatOut[i] = ((DatIn[i / 4] - '7') >> (i % 4)) & 0x01;208 }209else210 {211 DatOut[i] = ((DatIn[i / 4] - '0') >> (i % 4)) & 0x01;212 }213 }214 }215216// 表置换函数 OK217void TablePermute(bool *DatOut, bool *DatIn, const char *Table, int Num)218 {219int i = 0;220static bool Temp[256] = { 0 };221for (i = 0; i<Num; i++) // Num为置换的长度222 {223 Temp[i] = DatIn[Table[i] - 1]; // 原来的数据按对应的表上的位置排列224 }225 BitsCopy(DatOut, Temp, Num); // 把缓存Temp的值输出226 }227228// ⼦密钥的移位229void LoopMove(bool *DatIn, int Len, int Num) // 循环左移 Len数据长度 Num移动位数230 {231static bool Temp[256] = { 0 }; // 缓存 OK232 BitsCopy(Temp, DatIn, Num); // 将数据最左边的Num位(被移出去的)存⼊Temp233 BitsCopy(DatIn, DatIn + Num, Len - Num); // 将数据左边开始的第Num移⼊原来的空间234 BitsCopy(DatIn + Len - Num, Temp, Num); // 将缓存中移出去的数据加到最右边235 }236237// 按位异或238void Xor(bool *DatA, bool *DatB, int Num) // 异或函数239 {240int i = 0;241for (i = 0; i<Num; i++)242 {243 DatA[i] = DatA[i] ^ DatB[i]; // 异或244 }245 }246247// 输⼊48位输出32位与Ri异或248void S_Change(bool DatOut[32], bool DatIn[48]) // S盒变换249 {250int i, X, Y; // i为8个S盒251for (i = 0, Y = 0, X = 0; i<8; i++, DatIn += 6, DatOut += 4) // 每执⾏⼀次,输⼊数据偏移6位252 { // 每执⾏⼀次,输出数据偏移4位253 Y = (DatIn[0] << 1) + DatIn[5]; // af代表第⼏⾏254 X = (DatIn[1] << 3) + (DatIn[2] << 2) + (DatIn[3] << 1) + DatIn[4]; // bcde代表第⼏列255 ByteToBit(DatOut, &S_Box[i][Y][X], 4); // 把找到的点数据换为⼆进制256 }257 }258259// F函数260void F_Change(bool DatIn[32], bool DatKi[48]) // F函数261 {262static bool MiR[48] = { 0 }; // 输⼊32位通过E选位变为48位263 TablePermute(MiR, DatIn, E_Table, 48);264 Xor(MiR, DatKi, 48); // 和⼦密钥异或265 S_Change(DatIn, MiR); // S盒变换266 TablePermute(DatIn, DatIn, P_Table, 32); // P置换后输出267 }268269270271void SetKey(char KeyIn[8]) // 设置密钥获取⼦密钥Ki272 {273int i = 0;274static bool KeyBit[64] = { 0 }; // 密钥⼆进制存储空间275static bool *KiL = &KeyBit[0], *KiR = &KeyBit[28]; // 前28,后28共56276 ByteToBit(KeyBit, KeyIn, 64); // 把密钥转为⼆进制存⼊KeyBit277 TablePermute(KeyBit, KeyBit, PC1_Table, 56); // PC1表置换 56次278for (i = 0; i<16; i++)279 {280 LoopMove(KiL, 28, Move_Table[i]); // 前28位左移281 LoopMove(KiR, 28, Move_Table[i]); // 后28位左移282 TablePermute(SubKey[i], KeyBit, PC2_Table, 48);283// ⼆维数组 SubKey[i]为每⼀⾏起始地址284// 每移⼀次位进⾏PC2置换得 Ki 48位285 }286 }287288void PlayDes(char MesOut[8], char MesIn[8]) // 执⾏DES加密289 { // 字节输⼊ Bin运算 Hex输出290int i = 0;291static bool MesBit[64] = { 0 }; // 明⽂⼆进制存储空间 64位292static bool Temp[32] = { 0 };293static bool *MiL = &MesBit[0], *MiR = &MesBit[32]; // 前32位后32位294 ByteToBit(MesBit, MesIn, 64); // 把明⽂换成⼆进制存⼊MesBit295 TablePermute(MesBit, MesBit, IP_Table, 64); // IP置换296for (i = 0; i<16; i++) // 迭代16次297 {298 BitsCopy(Temp, MiR, 32); // 临时存储299 F_Change(MiR, SubKey[i]); // F函数变换300 Xor(MiR, MiL, 32); // 得到Ri301 BitsCopy(MiL, Temp, 32); // 得到Li302 }303 TablePermute(MesBit, MesBit, IPR_Table, 64);304 BitToHex(MesOut, MesBit, 64);305 }306307void KickDes(char MesOut[8], char MesIn[8]) // 执⾏DES解密308 { // Hex输⼊ Bin运算字节输出309int i = 0;310static bool MesBit[64] = { 0 }; // 密⽂⼆进制存储空间 64位311static bool Temp[32] = { 0 };312static bool *MiL = &MesBit[0], *MiR = &MesBit[32]; // 前32位后32位313 HexToBit(MesBit, MesIn, 64); // 把密⽂换成⼆进制存⼊MesBit 314 TablePermute(MesBit, MesBit, IP_Table, 64); // IP置换315for (i = 15; i >= 0; i--)316 {317 BitsCopy(Temp, MiL, 32);318 F_Change(MiL, SubKey[i]);319 Xor(MiL, MiR, 32);320 BitsCopy(MiR, Temp, 32);321 }322 TablePermute(MesBit, MesBit, IPR_Table, 64);323 BitToByte(MesOut, MesBit, 64);324 }main2.c验证算法的正确性和雪崩现象1.明⽂:12345678密钥:12345678密⽂:6E15D7EC4F9D4A062.修改⼀位明⽂明⽂:12345679密钥:12345678密⽂:48598F155CB7C5C93.修改⼀位密钥明⽂:12345678密钥:12345679密⽂:02AB45B02D446190-main.c1/*-------------------------------------------------------2 Data Encryption Standard 56位密钥加密64位数据3--------------------------------------------------------*/4 #include <stdlib.h>5 #include <stdio.h>6 #include "bool.h"// 位处理7 #include "tables.h"89void BitsCopy(bool *DatOut,bool *DatIn,int Len); // 数组复制1011void ByteToBit(bool *DatOut,char *DatIn,int Num); // 字节到位12void BitToByte(char *DatOut,bool *DatIn,int Num); // 位到字节1314void BitToHex(char *DatOut,bool *DatIn,int Num); // ⼆进制到⼗六进制 64位 to 4*16字符 15void HexToBit(bool *DatOut,char *DatIn,int Num); // ⼗六进制到⼆进制1617void TablePermute(bool *DatOut,bool *DatIn,const char *Table,int Num); // 位表置换函数 18void LoopMove(bool *DatIn,int Len,int Num); // 循环左移 Len长度 Num移动位数19void Xor(bool *DatA,bool *DatB,int Num); // 异或函数2021void S_Change(bool DatOut[32],bool DatIn[48]); // S盒变换22void F_Change(bool DatIn[32],bool DatKi[48]); // F函数2324void SetKey(char KeyIn[8]); // 设置密钥25void PlayDes(char MesOut[8],char MesIn[8]); // 执⾏DES加密26void KickDes(char MesOut[8],char MesIn[8]); // 执⾏DES解密27282930int main()31 {32int i=0;33char MesHex[16]={0}; // 16个字符数组⽤于存放 64位16进制的密⽂34char MyKey[8]={0}; // 初始密钥 8字节*835char YourKey[8]={0}; // 输⼊的解密密钥 8字节*836char MyMessage[8]={0}; // 初始明⽂3738/*-----------------------------------------------*/3940 printf("Welcome! Please input your Message(64 bit):\n");41 gets(MyMessage); // 明⽂42 printf("Please input your Secret Key:\n");43 gets(MyKey); // 密钥4445while(MyKey[i]!='\0') // 计算密钥长度46 {47 i++;48 }4950while(i!=8) // 不是8 提⽰错误51 {52 printf("Please input a correct Secret Key!\n");53 gets(MyKey);54 i=0;55while(MyKey[i]!='\0') // 再次检测56 {57 i++;58 }59 }6061 SetKey(MyKey); // 设置密钥得到⼦密钥Ki6263 PlayDes(MesHex,MyMessage); // 执⾏DES加密6465 printf("Your Message is Encrypted!:\n"); // 信息已加密66for(i=0;i<16;i++)67 {68 printf("%c ",MesHex[i]);69 }70 printf("\n\n");7172 printf("Please input your Secret Key to Deciphering:\n"); // 请输⼊密钥以解密73 gets(YourKey); // 得到密钥74 SetKey(YourKey); // 设置密钥7576 KickDes(MyMessage,MesHex); // 解密输出到MyMessage7778 printf("Deciphering Over !!:\n"); // 解密结束79for(i=0;i<8;i++)80 {81 printf("%c ",MyMessage[i]);82 }83 printf("\n\n");8485/*------------------------------------------------*/86 }8788/*-------------------------------89把DatIn开始的长度位Len位的⼆进制90复制到DatOut后91--------------------------------*/92void BitsCopy(bool *DatOut,bool *DatIn,int Len) // 数组复制 OK93 {94int i=0;95for(i=0;i<Len;i++)96 {97 DatOut[i]=DatIn[i];98 }99 }100101/*-------------------------------102字节转换成位函数103每8次换⼀个字节每次向右移⼀位104和1与取最后⼀位共64位105--------------------------------*/106void ByteToBit(bool *DatOut,char *DatIn,int Num) // OK107 {108int i=0;109for(i=0;i<Num;i++)110 {111 DatOut[i]=(DatIn[i/8]>>(i%8))&0x01;112 }113 }114115/*-------------------------------116位转换成字节函数117字节数组每8次移⼀位118位每次向左移与上⼀次或119---------------------------------*/120void BitToByte(char *DatOut,bool *DatIn,int Num) // OK121 {122int i=0;123for(i=0;i<(Num/8);i++)124 {125 DatOut[i]=0;126 }127for(i=0;i<Num;i++)128 {129 DatOut[i/8]|=DatIn[i]<<(i%8);130 }131 }132133134/*----------------------------------135⼆进制密⽂转换为⼗六进制136需要16个字符表⽰137-----------------------------------*/138void BitToHex(char *DatOut,bool *DatIn,int Num)139 {140int i=0;141for(i=0;i<Num/4;i++)142 {143 DatOut[i]=0;144 }145for(i=0;i<Num/4;i++)146 {147 DatOut[i] = DatIn[i*4]+(DatIn[i*4+1]<<1)148 +(DatIn[i*4+2]<<2)+(DatIn[i*4+3]<<3);149if((DatOut[i]%16)>9)150 {151 DatOut[i]=DatOut[i]%16+'7'; // 余数⼤于9时处理 10-15 to A-F152 } // 输出字符153else154 {155 DatOut[i]=DatOut[i]%16+'0'; // 输出字符156 }157 }158159 }160161/*---------------------------------------------162⼗六进制字符转⼆进制163----------------------------------------------*/164void HexToBit(bool *DatOut,char *DatIn,int Num)165 {166int i=0; // 字符型输⼊167for(i=0;i<Num;i++)168 {169if((DatIn[i/4])>'9') // ⼤于9170 {171 DatOut[i]=((DatIn[i/4]-'7')>>(i%4))&0x01;172 }173else174 {175 DatOut[i]=((DatIn[i/4]-'0')>>(i%4))&0x01;176 }177 }178 }179180// 表置换函数 OK181void TablePermute(bool *DatOut,bool *DatIn,const char *Table,int Num)182 {183int i=0;184static bool Temp[256]={0};185for(i=0;i<Num;i++) // Num为置换的长度186 {187 Temp[i]=DatIn[Table[i]-1]; // 原来的数据按对应的表上的位置排列188 }189 BitsCopy(DatOut,Temp,Num); // 把缓存Temp的值输出190 }191192// ⼦密钥的移位193void LoopMove(bool *DatIn,int Len,int Num) // 循环左移 Len数据长度 Num移动位数194 {195static bool Temp[256]={0}; // 缓存 OK196 BitsCopy(Temp,DatIn,Num); // 将数据最左边的Num位(被移出去的)存⼊Temp 197 BitsCopy(DatIn,DatIn+Num,Len-Num); // 将数据左边开始的第Num移⼊原来的空间198 BitsCopy(DatIn+Len-Num,Temp,Num); // 将缓存中移出去的数据加到最右边199 }200201// 按位异或202void Xor(bool *DatA,bool *DatB,int Num) // 异或函数203 {204int i=0;205for(i=0;i<Num;i++)206 {207 DatA[i]=DatA[i]^DatB[i]; // 异或208 }209 }210211// 输⼊48位输出32位与Ri异或212void S_Change(bool DatOut[32],bool DatIn[48]) // S盒变换213 {214int i,X,Y; // i为8个S盒215for(i=0,Y=0,X=0;i<8;i++,DatIn+=6,DatOut+=4) // 每执⾏⼀次,输⼊数据偏移6位216 { // 每执⾏⼀次,输出数据偏移4位217 Y=(DatIn[0]<<1)+DatIn[5]; // af代表第⼏⾏218 X=(DatIn[1]<<3)+(DatIn[2]<<2)+(DatIn[3]<<1)+DatIn[4]; // bcde代表第⼏列219 ByteToBit(DatOut,&S_Box[i][Y][X],4); // 把找到的点数据换为⼆进制220 }221 }222223// F函数224void F_Change(bool DatIn[32],bool DatKi[48]) // F函数225 {226static bool MiR[48]={0}; // 输⼊32位通过E选位变为48位227 TablePermute(MiR,DatIn,E_Table,48);228 Xor(MiR,DatKi,48); // 和⼦密钥异或229 S_Change(DatIn,MiR); // S盒变换230 TablePermute(DatIn,DatIn,P_Table,32); // P置换后输出231 }232233234235void SetKey(char KeyIn[8]) // 设置密钥获取⼦密钥Ki236 {237int i=0;238static bool KeyBit[64]={0}; // 密钥⼆进制存储空间239static bool *KiL=&KeyBit[0],*KiR=&KeyBit[28]; // 前28,后28共56240 ByteToBit(KeyBit,KeyIn,64); // 把密钥转为⼆进制存⼊KeyBit 241 TablePermute(KeyBit,KeyBit,PC1_Table,56); // PC1表置换 56次242for(i=0;i<16;i++)243 {244 LoopMove(KiL,28,Move_Table[i]); // 前28位左移245 LoopMove(KiR,28,Move_Table[i]); // 后28位左移246 TablePermute(SubKey[i],KeyBit,PC2_Table,48);247// ⼆维数组 SubKey[i]为每⼀⾏起始地址248// 每移⼀次位进⾏PC2置换得 Ki 48位249 }250 }251252void PlayDes(char MesOut[8],char MesIn[8]) // 执⾏DES加密253 { // 字节输⼊ Bin运算 Hex输出254int i=0;255static bool MesBit[64]={0}; // 明⽂⼆进制存储空间 64位256static bool Temp[32]={0};257static bool *MiL=&MesBit[0],*MiR=&MesBit[32]; // 前32位后32位258 ByteToBit(MesBit,MesIn,64); // 把明⽂换成⼆进制存⼊MesBit 259 TablePermute(MesBit,MesBit,IP_Table,64); // IP置换260for(i=0;i<16;i++) // 迭代16次261 {262 BitsCopy(Temp,MiR,32); // 临时存储263 F_Change(MiR,SubKey[i]); // F函数变换264 Xor(MiR,MiL,32); // 得到Ri265 BitsCopy(MiL,Temp,32); // 得到Li266 }267 TablePermute(MesBit,MesBit,IPR_Table,64);268 BitToHex(MesOut,MesBit,64);269 }270271void KickDes(char MesOut[8],char MesIn[8]) // 执⾏DES解密272 { // Hex输⼊ Bin运算字节输出273int i=0;274static bool MesBit[64]={0}; // 密⽂⼆进制存储空间 64位275static bool Temp[32]={0};276static bool *MiL=&MesBit[0],*MiR=&MesBit[32]; // 前32位后32位277 HexToBit(MesBit,MesIn,64); // 把密⽂换成⼆进制存⼊MesBit 278 TablePermute(MesBit,MesBit,IP_Table,64); // IP置换279for(i=15;i>=0;i--)280 {281 BitsCopy(Temp,MiL,32);282 F_Change(MiL,SubKey[i]);283 Xor(MiL,MiR,32);284 BitsCopy(MiR,Temp,32);285 }286 TablePermute(MesBit,MesBit,IPR_Table,64);287 BitToByte(MesOut,MesBit,64);288 }-tables.h1/*-------------------------------------------------------------2置换表3-------------------------------------------------------------*/45 #ifndef _TABLES_H_ // 防重复编译6#define _TABLES_H_78// 对明⽂执⾏IP置换得到L0,R0 (L左32位,R右32位) [明⽂操作]9const char IP_Table[64]={1058,50,42,34,26,18,10, 2,60,52,44,36,28,20,12, 4,1162,54,46,38,30,22,14, 6,64,56,48,40,32,24,16, 8,1257,49,41,33,25,17, 9, 1,59,51,43,35,27,19,11, 3,1361,53,45,37,29,21,13, 5,63,55,47,39,31,23,15, 714 };1516// 对迭代后的L16,R16执⾏IP逆置换,输出密⽂17const char IPR_Table[64]={1840, 8,48,16,56,24,64,32,39, 7,47,15,55,23,63,31,1938, 6,46,14,54,22,62,30,37, 5,45,13,53,21,61,29,2036, 4,44,12,52,20,60,28,35, 3,43,11,51,19,59,27,2134, 2,42,10,50,18,58,26,33, 1,41, 9,49,17,57,2522 };2324/*--------------------------- 迭代法则 ----------------------------*/2526// F函数,32位的R0进⾏E变换,扩为48位输出 (R1~R16) [备⽤A] [明⽂操作]27static char E_Table[48]={2832, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9,298, 9,10,11,12,13,12,13,14,15,16,17,3016,17,18,19,20,21,20,21,22,23,24,25,3124,25,26,27,28,29,28,29,30,31,32, 132 };3334// ⼦密钥K(i)的获取密钥为K 抛弃第6,16,24,32,40,48,64位 [密钥操作]35// ⽤PC1选位分为前28位C0,后28位D0 两部分36static char PC1_Table[56]={3757,49,41,33,25,17, 9, 1,58,50,42,34,26,18,3810, 2,59,51,43,35,27,19,11, 3,60,52,44,36,3963,55,47,39,31,23,15, 7,62,54,46,38,30,22,4014, 6,61,53,45,37,29,21,13, 5,28,20,12, 441 };4243// 对C0,D0分别进⾏左移,共16次,左移位数与下⾯对应 [密钥操作]44static char Move_Table[16]={451, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 146 };4748// C1,D1为第⼀次左移后得到,进⾏PC2选位,得到48位输出K1 [备⽤B] [密钥操作] 49static char PC2_Table[48]={5014,17,11,24, 1, 5, 3,28,15, 6,21,10,5123,19,12, 4,26, 8,16, 7,27,20,13, 2,5241,52,31,37,47,55,30,40,51,34,33,48,5344,49,39,56,34,53,46,42,50,36,29,3254 };5556/*------------- F函数备⽤A和备⽤B 异或得到48位输出 ---------------*/5758// 异或后的结果48位分为8组,每组6位,作为8个S盒的输⼊ [组合操作]59// S盒以6位作为输⼊(8组),4位作为输出(4*(8组)=32位)60// S⼯作原理假设输⼊为A=abcdef ,则bcde所代表的数是0-15之间的61// ⼀个数记为 X=bcde ,af代表的是0-3之间的⼀个数,记为 Y=af62// 在S1的X列,Y⾏找到⼀个数Value,它在0-15之间,可以⽤⼆进制表⽰63// 所以为4bit (共32位)64static char S_Box[8][4][16]={65//S16614, 4,13, 1, 2,15,11, 8, 3,10, 6,12, 5, 9, 0, 7,670,15, 7, 4,14, 2,13, 1,10, 6,12,11, 9, 5, 3, 8,684, 1,14, 8,13, 6, 2,11,15,12, 9, 7, 3,10, 5, 0,6915,12, 8, 2, 4, 9, 1, 7, 5,11, 3,14,10, 0, 6,13,70//S27115, 1, 8,14, 6,11, 3, 4, 9, 7, 2,13,12, 0, 5,10,723,13, 4, 7,15, 2, 8,14,12, 0, 1,10, 6, 9,11, 5,730,14, 7,11,10, 4,13, 1, 5, 8,12, 6, 9, 3, 2,15,7413, 8,10, 1, 3,15, 4, 2,11, 6, 7,12, 0, 5,14, 9,75//S37610, 0, 9,14, 6, 3,15, 5, 1,13,12, 7,11, 4, 2, 8,7713, 7, 0, 9, 3, 4, 6,10, 2, 8, 5,14,12,11,15, 1,7813, 6, 4, 9, 8,15, 3, 0,11, 1, 2,12, 5,10,14, 7,791,10,13, 0, 6, 9, 8, 7, 4,15,14, 3,11, 5, 2,12,80//S4817,13,14, 3, 0, 6, 9,10, 1, 2, 8, 5,11,12, 4,15,8213, 8,11, 5, 6,15, 0, 3, 4, 7, 2,12, 1,10,14, 9,8310, 6, 9, 0,12,11, 7,13,15, 1, 3,14, 5, 2, 8, 4,843,15, 0, 6,10, 1,13, 8, 9, 4, 5,11,12, 7, 2,14,85//S5862,12, 4, 1, 7,10,11, 6, 8, 5, 3,15,13, 0,14, 9,8714,11, 2,12, 4, 7,13, 1, 5, 0,15,10, 3, 9, 8, 6,884, 2, 1,11,10,13, 7, 8,15, 9,12, 5, 6, 3, 0,14,8911, 8,12, 7, 1,14, 2,13, 6,15, 0, 9,10, 4, 5, 3,90//S69112, 1,10,15, 9, 2, 6, 8, 0,13, 3, 4,14, 7, 5,11,9210,15, 4, 2, 7,12, 0, 5, 6, 1,13,14, 0,11, 3, 8,939,14,15, 5, 2, 8,12, 3, 7, 0, 4,10, 1,13,11, 6,944, 3, 2,12, 9, 5,15,10,11,14, 1, 7, 6, 0, 8,13,95//S7964,11, 2,14,15, 0, 8,13, 3,12, 9, 7, 5,10, 6, 1,9713, 0,11, 7, 4, 0, 1,10,14, 3, 5,12, 2,15, 8, 6,981, 4,11,13,12, 3, 7,14,10,15, 6, 8, 0, 5, 9, 2,996,11,13, 8, 1, 4,10, 7, 9, 5, 0,15,14, 2, 3,12,100//S810113, 2, 8, 4, 6,15,11, 1,10, 9, 3,14, 5, 0,12, 7,1021,15,13, 8,10, 3, 7, 4,12, 5, 6,11, 0,14, 9, 2,1037,11, 4, 1, 9,12,14, 2, 0, 6,10,13,15, 3, 5, 8,1042, 1,14, 7, 4,10, 8,13,15,12, 9, 0, 3, 5, 6,11105 };106107// F函数最后第⼆步,对S盒输出的32进⾏P置换 [组合操作] 108// 输出的值参与⼀次迭代:109// L(i)=R(i-1)110// R(i)=L(i-1)^f(R(i-1),K(i)) 异或111static char P_Table[32]={11216, 7,20,21,29,12,28,17, 1,15,23,26, 5,18,31,10,1132, 8,24,14,32,27, 3, 9,19,13,30, 6,22,11, 4,25114 };115116// 16个⼦密钥K(1~16)117static bool SubKey[16][48]={0};118119#endif-bool.h1 #ifndef __BOOL_H__2#define __BOOL_H__34 typedef enum5 {6false = 0,7true = 18 } bool;910#endif。
DES实验报告DES加解密算法实现⼀、实验⽬的在这⼀实验中,⽤VC++实现DES加解密算法。
完成实验后,将能够深⼊理解DES加解密算法及其在VC++中的实现过程。
⼆、实验条件熟悉VC++开发环境和有关DES算法知识,安装了VC++6.0系统的计算机。
三、任务描述对数据进⾏加密传输能有效地保证数据的机密性,DES算法是⼀个保护数据的机密性的经典算法,本实验在VC++环境中实现DES算法。
在VC++中建⽴⼀个项⽬,并将资料盘中的DES程序代码添⼊项⽬中,实现加/解密功能。
四、操作步骤1.进⼊Microsoft Vilual C++ 6.0系统界⾯,选择菜单中的File--New,出现New 对话框。
2.在对话框中,选择Projects页,在左侧的列表中选择MFC AppWizard[exe],在Project name⽂本框中输⼊新建项⽬的名称,如DES加解密算法,在Location ⽂本框中选择项⽬存储路径。
单击OK按钮出现MFC AppWizard-step1对话框。
3.在对话框中,选择Dialog based,单击Next按钮。
4.之后出现的对话框MFC AppWizard-step 2 of 4、MFC AppWizard-step 3 of 4中均单击Next按钮。
MFC AppWizard-step 4 of 4中单击Finish,出现New Project Information对话框。
单击OK按钮,⼀个新项⽬就建成了。
5. 在对话框上添加控件资源,如图1所⽰。
6.在VC++菜单中选择View中ClassWizard命令,为控件资源定义变量,出现对话框。
可以看到类的所有可被定义变量的控件资源,为每个资源分别定义变量。
如:在列表中选择IDC_EDIT1,然后单击Add Variable按钮,在其后出现的对话框中输⼊变量名即可。
图1 DES加密解密对话框7.添加其他变量,右击CDESDlg在弹出的菜单中选择Add Member Variable…命令,在新出现的对话框中,输⼊变量类型、变量名,选择变量的访问类型。
des算法的实验报告DES算法实验报告DES(Data Encryption Standard)算法是一种对称密钥加密算法,广泛应用于信息安全领域。
本实验旨在通过实验DES算法的加密和解密过程,以及密钥长度对加密效果的影响,来深入了解DES算法的原理和应用。
实验一:加密和解密过程首先,我们使用一个明文进行加密实验。
选择一个64位的明文作为输入,同时使用一个64位的密钥进行加密。
经过DES算法加密后,得到的密文长度也为64位。
然后,我们使用相同的密钥对密文进行解密,得到原始的明文。
实验结果表明,DES算法能够对明文进行有效的加密,并且使用相同的密钥能够对密文进行解密,得到原始的明文。
这说明DES算法是一种可靠的加密算法,能够保护数据的安全性。
实验二:密钥长度对加密效果的影响在第二个实验中,我们对不同长度的密钥进行加密实验,观察加密效果的变化。
我们分别使用56位、64位和128位的密钥进行加密,然后比较不同长度密钥的加密效果。
实验结果显示,密钥长度对加密效果有显著影响。
使用128位的密钥进行加密,能够得到更加安全的密文,而使用56位的密钥进行加密,则容易受到攻击。
这表明密钥长度是影响DES算法加密效果的重要因素。
结论通过本实验,我们深入了解了DES算法的加密和解密过程,以及密钥长度对加密效果的影响。
DES算法是一种可靠的加密算法,能够有效保护数据的安全性。
同时,密钥长度对加密效果有显著影响,因此在实际应用中需要选择足够长度的密钥来保障数据的安全。
总之,DES算法在信息安全领域有着重要的应用价值,通过本实验的学习,我们对DES算法有了更深入的了解,为进一步研究和应用提供了重要的参考。
实验名称实验三加密编码--------DES数据加密算法一、实验目的1. 了解DES加密,解密过程;2. 在Visual C++环境中运用C语言实现DES加密,解密;3. 会用DES加密方法对文件进行加密。
二、实验内容1. 在Visual C++环境中运用C语言熟练实现DES加密;2. 在Visual C++环境中运用C语言熟练实现DES解密。
三、实验原理1. DES加密的定义DES是一种分组密码,也是一种单钥密码。
2. DES的特点明文分组比较短、密钥较短、密码生命周期较短、运算速度较慢。
3. DES加密算法描述在DES中明文分组长为64比特,密钥长为56比特。
明文处理过程大致分为3个阶段,首先为一个初始置换IP,用于重排明文分组的64比特数据。
然后是相同功能的16轮迭代,每轮中都有置换和代换运算,第16轮变换的输出分为左右两半,并被交换次序。
最后再经过一个逆初始置换(IP的逆)从而产生64比特的密文。
在上述运算中还涉及密钥的产生和运算。
4. DES解密算法描述DES的解密过程和DES的加密过程完全类似,只不过将16轮的子密钥序列K1,K2,…,K16的顺序倒过来。
即第一轮用第16个子密钥K16,第二轮用K15,以此类推。
四、实验步骤1. DES加密步骤(1)初始IP置换表2-1 初始置换IP58 50 42 34 26 18 10 260 52 44 36 28 20 12 462 54 46 38 30 22 14 664 56 48 40 32 24 16 859 51 43 35 27 19 11 361 53 45 37 29 21 13 563 55 47 39 31 23 15 7说明:上表元素下标从1开始,按行优先顺序排列,表中数字代表经过IP置换后,在该位置的元素对应的在原分组中元素的下标。
如:变换后第一个位置的元素为原来下标为58的元素,变换后下标为2的元素为原来下标为50的元素。
《网络安全技术》实验姓名系别实验地点学号年级班实验时间成绩评定教师签字实验项目DES加密解密程序设计与实现实验目的:1、理解DES加密与解密的程序设计算法思想2、编写DES加密与解密程序,实现对明文的加密与解密,加深对数据加密与解密的理解,掌握DES加密算法思想,提高网络安全的编程能力。
所用软件:TC、VC等其它编程工具实现实验内容:掌握DES算法,编写DES算法。
1)初始置换初始置换在第一轮运算之前执行,对输入分组实施如下表所示的变换。
此表应从左向右、从上向下读。
例如,初始置换把明文的第58位换到第1位的位置,把第50位换到第2位的位置,把第42位换到第3位的位置,等等。
58 50 42 34 26 18 10 2 60 52 44 36 28 20 12 462 54 46 38 30 22 14 6 64 56 48 40 32 24 16 857 49 41 33 25 17 9 1 59 51 43 35 27 19 11 361 53 45 37 29 21 13 5 63 55 47 39 31 23 15 7在将这64位数据分为左右两部分,每部分分别为32位,将左32位留下,将右32位按照下表进行排列32 1 2 3 4 5 4 5 6 7 8 98 9 10 11 12 13 12 13 14 15 16 1716 17 18 19 20 21 20 21 22 23 24 2524 25 26 27 28 29 28 29 30 31 32 12)密钥置换一开始,由于不考虑每个字节的第8位,DES的密钥由64位减至56位,如下表所示。
每个字节第8位可作为奇偶校验位以确保密钥不发生错误。
57 49 41 33 25 17 9 158 50 42 34 26 1810 259 51 43 35 27 19 11 360 52 44 3663 55 47 39 31 23 15 7 62 54 46 38 30 2214 661 53 45 37 29 21 13 528 20 12 4接着,56位密钥被分成两部分,每部分28位。