DES_加密解密算法的C++实现--实验报告
【精品】DES算法实验报告
【精品】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加密解密实验报告实验报告题目: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实验报告
DES
[实验目的] C语言实现des加密解密
[实验原理]
1.DES的加密过程: 第一阶段:初始置换IP。在第一轮迭代之前,需要加密的64位明文首先通过初始置换IP 的作用,对输 入分组实施置换。最后,按照置换顺序,DES将64位的置换结果分为左右两部分,第1位到第32位记为 L0,第33位到第64位记为R0。 第二阶段:16次迭代变换。DES采用了典型的Feistel结构,是一个乘积结构的迭代密码算法。其算法的 核心是算法所规定的16次迭代变换。DES算法的16才迭代变换具有相同的结构,每一次迭代变换都以前 一次迭代变换的结果和用户密钥扩展得到的子密钥Ki作为输入;每一次迭代变换只变换了一半数据,它 们将输入数据的右半部分经过函数f后将其输出,与输入数据的左半部分进行异或运算,并将得到的结果 作为新的有半部分,原来的有半部分变成了新的左半部分。用下面的规则来表示这一过程(假设第i次迭 代所得到的结果为LiRi): Li = Ri-1; Ri = Li-1⊕ f(Ri-1,Ki);在最后一轮左与右半部分并未变换,而是直接 将R16 L16并在一起作为未置换的输入。 第三阶段:逆(初始)置换。 他是初始置换IP的逆置换,记为IP-1。在对16次迭代的结果(R16 L16) 再使用逆置换IP-1后,得到的结果即可作为DES加密的密文Y输出,即Y = IP-1 (R16 L16)。 2.DES解密过程: DES的解密算法与其加密算法使用的算法过程相同。两者的不同之处在于解密时子密钥Ki的使用顺序与 加密时相反,如果子密钥为K1K2… K16,那么解密时子密钥的使用顺序为K16K15… K1,即使用DES解密 算法进行解密时,将以64位密文作为输入,第1次迭代运算使用子密钥K16,第2次迭代运算使用子密钥 K15,… … ,第16 次迭代使用子密钥K1,其它的运算与加密算法相同。这样,最后输出的是64位明文。
des密码算法实验c语言
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 密码算法。
C语言实现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实验报告一、实验目的实现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];。
DES_加密解密算法的C++实现--实验报告
DES_加密解密算法的C++实现--实验报告1实验⼀1、实验题⽬利⽤C/C++编程实现DES加密算法或MD5加密算法。
我选择的是⽤C++语⾔实现DES的加密算法。
2、实验⽬的通过编码实现DES算法或MD5算法,深⼊掌握算法的加密原理,理解其实际应⽤价值,同时要求⽤C/C++语⾔实现该算法,让我们从底层开始熟悉该算法的实现过程3、实验环境操作系统:WIN7旗舰版开发⼯具:Visual Studio 2010旗舰版开发语⾔: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的加密,代码的主要⼏个函数如下:代码// : 定义控制台应⽤程序的⼊⼝点。
//#include "" #include "" #include #include #include using namespace std;//置换矩阵int IP_EX[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, 5 6, 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 IP_ANTEX[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, 41, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25 };//扩展矩阵int EXTEND[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, 1, 2};//S盒int S[8][4][16]= { { {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}}, { {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, 1 0, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9} }, { {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} }, { { 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} }, { {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} },{ {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, 1 3, 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}}, { {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}}, { {13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 1 4, 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}}};int DIREX[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 };//左移移位表int MOVELEFT[16]= { 1,1,2,2,2,2,2,2, 1,2,2,2,2,2,2,1};//压缩换位表2int CutEX[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};typedef char ElemType;ElemType subsec[16][48];//Byte转bitint ByteToBit(ElemType ch,ElemType bit[8]) {for(int index = 7;index >= 0;index--) {bit[index] = (ch>>index)&1; //cout<<(int)bit[index]; }return 0; }//bit转Byteint BitToByte(ElemType bit[8],ElemType &ch) { ElemType tempch=0; Ele mType tempbit[8]; for(int i=0;i<8;i++) {tempbit[i]=bit[i];}tempbit[7]=0;for(int index = 7;index >=0;index--){tempch=tempch|(tempbit[index]<<(index)); } ch=tempch;//cout<<(char)tempch<return 0;}//按64位分⼀组void Get64Bit(ElemType ch[8],ElemType bit[64]) { ElemType temp[8]; i nt count=0; for(int i=0;i<8;i++) { ByteToBit(ch[i],temp); for (int j=0;j<8;j++) { bit[count*8+j]=temp[7-j];}count++;}}//初始置换void InitialEX(ElemType Inorder[64],ElemType Disorder[64]) { for(int i= 0;i<64;i++) { Disorder[i]=Inorder[IP_EX[i]-1]; }}//逆置换void AntiEx(ElemType Disorder[64]) { ElemType temp[64]; for(int i=0; i<64;i++) {temp[i]=Disorder[i];}for(int i=0;i<64;i++) { Disorder[i]=temp[IP_ANTEX[i]-1];}}//扩展置换void ExpandEX(ElemType RightMsg[32],ElemType ExpandMsg[48]) {for(int i=0;i<48;i++) { ExpandMsg[i]=RightMsg[EXTEND[i]-1];}}//16轮加密迭代void MoveLeft(ElemType C[28],ElemType D[28],ElemType L0[32],ElemType R0[32 ]) { ElemType Secret[48]; //⼦密钥ElemType Result[48]; //每轮异或结果ElemType Sout[32];//每轮S盒输出ElemType DirOut[32]; //直接置换输出ElemType RResult[32]; ElemType LResult[32]; ElemType ExpandMsg[48];ElemType temp[32]; for(int i=0;i<32;i++) { LResult[i]=L0[i];RResult[i]=R0[i];}for(int i=0;i<16;i++) { if(MOVELEFT[i]==1) { for(int j= 0;j<27;j++) { C[i]=C[i+1];}C[27]=0;} else { for(int j=0;j<26;j++) {C[i]=C[i+2]; }C[26]=0; C[27]=0;}ExpandEX(RResult,ExpandMsg); GetCD48(C,D,Secret);for(int j=0;j<48;j++){subsec[15-i][j]=Secret[j]; //获取界⾯的⼦密钥}XOR(ExpandMsg,Secret,Result); //S盒置换getSOut(Result,Sout); //直接置换DirExchange(Sout,DirOut); //与L进⾏异或XORLR(DirOut,LResult,temp); for(int i=0;i<32;i++) { LResu lt[i]=RResult[i];}for(int i=0;i<32;i++) {RResult[i]=temp[i]; }for(int i=0;i<32;i++) { L0[i]=LResult[i]; R0[i]=RResult [i];}}/*cout<<"zuo"<}}cout<<"右边"<{cout<}}*/LResult[j]=RResult[j];}for(int j=0;j<32;j++) { RResult[j]=temp[j]; }。
C语言实现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加密解密实验报告
用一维数组存储初始置换表 IP、逆置换表 IP_1、密钥置换表 PC_1、压缩密钥置换表 PC_2、
循环左移表、扩展置换表 E 盒和 P 置换盒,用三维数组存放 8 个 4*16 的 S 盒。
实现位置:Des.h 的 private 成员 代码如下:
// 初始置换表IP int IP[64] = { 58, 50, 42, 34, 26, 18, 10, 2,
3)终结置换 IP-1:按照终结置换表进行终结置换,64 位输出就是密文。 其中,在每一轮的子加密过程中,48 位的明文数据要与 48 位的子密钥进行异或运算。 子密钥的产生过程如下:
<1>对输入的密钥经过 PC1 置换输出 56 位数据,划分为 2 部分,每部分 28 位,左半部 分记为 C,右半部分记为 D。
1. DES 加密 ......................................................................................2 2. DES 解密 ......................................................................................5 四、程序实现 ...................................................................................... 5 1. 存储置换表的取值......................................................................5 2. 生成子密钥 ................................................................................. 8 3. 实现 F 函数 .................................................................................9 4. DES 加密 ....................................................................................10 5. 测试代码 ................................................................................... 11 五、程序运行初值及结果 ................................................................. 14 六、实验体会 .................................................................................... 14
实验一:C语言实现DES加解密算法
实验⼀: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加密解密算法实现二、实验环境:1、操作系统:Windows XP及以上2、编程工具:Visual C++ 6.0三、实验原理:DES算法为密码体制中的对称密码体制,又被成为美国数据加密标准,是1972年美国IBM公司研制的对称密码体制加密算法。
明文按64位进行分组, 密钥长64位,密钥事实上是56位参与DES运算(第8、16、24、32、40、48、56、64位是校验位,使得每个密钥都有奇数个1)分组后的明文组和56位的密钥按位替代或交换的方法形成密文组的加密方法。
基本原理:其入口参数有三个:key、data、mode。
key为加密解密使用的密钥,data为加密解密的数据,mode为其工作模式。
当模式为加密模式时,明文按照64位进行分组,形成明文组,key用于对数据加密,当模式为解密模式时,key用于对数据解密。
实际运用中,密钥只用到了64位中的56位,这样才具有高的安全性。
算法特点:分组比较短、密钥太短、密码生命周期短、运算速度较慢。
四、算法流程设计:1、DES算法整体结构:2、16轮迭代:3、子密钥产生:4、f函数:五、算法实现:1、部分函数定义:static void F_func(bool In[], const bool Ki[]);// F 函数static void S_func(bool Out[], const bool In[]);// S 盒代替static void Transform(bool *Out, bool *In, const char *Table, int len);// 变换static void Xor(bool *InA, const bool *InB, int len);// 异或static void RotateL(bool *In, int len, int loop);// 循环左移static void ByteToBit(bool *Out, const char *In, int bits);// 字节组转换成位组static void BitToByte(char *Out, const bool *In, int bits);// 位组转换成字节组static void BitToHex(char *Out,const bool *In, int bits);// 将二进制转换为十六进制2、主要功能模块:void Des_SetKey(const char Key[]){ //生成子密钥static bool K[64], *KL = &K[0], *KR = &K[28];ByteToBit(K, Key, 64);for(int i=0; i<16; i++){RotateL(KL, 28, LOOP_Table[i]); //循环左移RotateL(KR, 28, LOOP_Table[i]);Transform(SubKey[i], K, PC2_Table, 48); //PC2变换}}void Des_Run(char Out1[],char Out2[], char In[], bool Type){ //des加密解密过程static bool M[64], Tmp[32], *Li = &M[0], *Ri = &M[32];ByteToBit(M, In, 64);Transform(M, M, IP_Table, 64); //IP置换if( Type == ENCRYPT ){ //加密for(int i=0; i<16; i++) {memcpy(Tmp, Ri, 32);F_func(Ri, SubKey[i]); //F函数Xor(Ri, Li, 32); //异或memcpy(Li, Tmp, 32);}}else{ //解密for(int i=15; i>=0; i--) {memcpy(Tmp, Li, 32);F_func(Li, SubKey[i]); //F函数Xor(Li, Ri, 32); //异或memcpy(Ri, Tmp, 32);}}Transform(M, M, IPR_Table, 64); //IP-1置换BitToByte(Out1, M, 64); //Out1为字符形式密文 BitToHex(Out2, M, 64); //Out2为十六进制数形式密文}void F_func(bool In[], const bool Ki[]){ //F函数static bool MR[48];Transform(MR, In, E_Table, 48); //E扩展Xor(MR, Ki, 48); //异或密钥S_func(In, MR); //S盒代换Transform(In, In, P_Table, 32); //P置换}3、调试中遇到的问题及解决办法问题:通过BitToByte()函数转换只能看到字符形式的密文,为乱码。
DES实验报告
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_加密解密算法的C++实现--实验报告
分组密码实验报告一、DES算法的实现1.DES简介本世纪五十年代以来,密码学研究领域出现了最具代表性的两大成就。
其中之一就是1971年美国学者塔奇曼(Tuchman)和麦耶(Meyer)根据信息论创始人香农(Shannon)提出的“多重加密有效性理论”创立的,后于1977年由美国国家标准局颁布的数据加密标准。
DES密码实际上是Lucifer密码的进一步发展。
它是一种采用传统加密方法的区组密码。
它的算法是对称的,既可用于加密又可用于解密。
美国国家标准局1973年开始研究除国防部外的其它部门的计算机系统的数据加密标准,于1973年5月15日和1974年8月27日先后两次向公众发出了征求加密算法的公告。
加密算法要达到的目的通常称为DES密码算法要求主要为以下四点:提供高质量的数据保护,防止数据未经授权的泄露和未被察觉的修改;具有相当高的复杂性,使得破译的开销超过可能获得的利益,同时又要便于理解和掌握DES密码体制的安全性应该不依赖于算法的保密,其安全性仅以加密密钥的保密为基础实现经济,运行有效,并且适用于多种完全不同的应用。
1977年1月,美国政府颁布:采纳IBM公司设计的方案作为非机密数据的正式数据加密标准(DES枣Data Encryption Standard)。
目前在这里,随着三金工程尤其是金卡工程的启动,DES算法在POS、ATM、磁卡及智能卡(IC卡)、加油站、高速公路收费站等领域被广泛应用,以此来实现关键数据的保密,如信用卡持卡人的PIN的加密传输,IC卡与POS间的双向认证、金融交易数据包的MAC 校验等,均用到DES算法。
DES算法的入口参数有三个:Key、Data、Mode。
其中Key为8个字节共64位,是DES算法的工作密钥;Data也为8个字节64位,是要被加密或被解密的数据;Mode为DES 的工作方式,有两种:加密或解密。
DES算法是这样工作的:如Mode为加密,则用Key 去把数据Data进行加密,生成Data的密码形式(64位)作为DES的输出结果;如Mode为解密,则用Key去把密码形式的数据Data解密,还原为Data的明码形式(64位)作为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 加密解密算法的C完成 实验报告
美国国家标准局 1973 年开始研究除国防部外的其它部门的计算机系统的数据加密标准, 于 1973 年 5 月 15 日和 1974 年 8 月 27 日先后两次向公众发出了征求加密算法的公告。加 密算法要达到的目的通常称为 DES 密码算法要求主要为以下四点:
DES 算法的入口参数有三个:Key、Data、Mode。其中 Key 为 8 个字节共 64 位,是 DES 算法的工作密钥;Data 也为 8 个字节 64 位,是要被加密或被解密的数据;Mode 为 DES 的工作方式,有两种:加密或解密。
DES 算法是这样工作的:如 Mode 为加密,则用 Key 去把数据 Data 进行加密, 生成 Data 的密码形式(64 位)作为 DES 的输出结果;如 Mode 为解密,则用 Key 去把密码形 式的数据 Data 解密,还原为 Data 的明码形式(64 位)作为 DES 的输出结果。在通信网络 的两端,双方约定一致的 Key,在通信的源点用 Key 对核心数据进行 DES 加密,然后以密 码形式在公共通信网(如电话网)中传输到通信网络的终点,数据到达目的地后,用同样 的 Key 对密码数据进行解密,便再现了明码形式的核心数据。这样,便保证了核心数据 (如 PIN、MAC 等)在公共通信网中传输的安全性和可靠性。
目前在这里,随着三金工程尤其是金卡工程的启动,DES 算法在 POS、ATM、磁卡及 智能卡(IC 卡)、加油站、高速公路收费站等领域被广泛应用,以此来实现关键数据的保 密,如信用卡持卡人的 PIN 的加密传输,IC 卡与 POS 间的双向认证、金融交易数据包的 MAC 校验等,均用到 DES 算法。
DES加密解密实验报告
DES加密解密实验报告DES(Data Encryption Standard),是一种对称密钥加密算法,由IBM在1975年推出。
DES密钥长度为56位,分为加密和解密两个过程。
实验目的:1.了解DES算法的原理和流程。
2.通过实际操作,掌握DES算法的加密和解密过程。
3.分析DES算法的安全性和应用场景。
实验步骤:1.选择合适的明文和密钥。
明文可以是一段文字或者数字,密钥为56位的二进制数。
2.对明文进行填充。
DES算法要求明文长度必须为64位,如果不满足则需要进行填充。
3.初始置换(IP)过程。
将64位明文按照特定的规则进行置换,得到加密前的明文。
4.将置换后的明文分为左右两部分,每部分32位。
5.进行16轮的加密操作,每轮包括以下步骤:a.将右半部分作为下一轮的左半部分。
b.根据其中一种特定规则,对右半部分进行扩展和置换操作,得到48位的数据。
c.将48位的数据和轮密钥进行异或操作,得到新的48位数据。
d.将新得到的48位数据分为8个6位数据,并进行S盒置换操作,得到4位数据。
e.将4位数据按照特定规则进行置换,得到32位数据。
f.将32位数据和左半部分进行异或操作,得到新的32位数据。
6.经过16轮的加密操作之后,左右两部分交换位置。
7.最终进行反置换(FP)操作,得到密文。
实验结果:1.明文填充:HELLO->HELLO0。
2.初始置换:HELLO0->LHLOEO0。
3.左右两部分:LHLOEO0。
4.加密过程(以第一轮为例):a.L1=RO,R1=LO实验分析:DES算法通过16轮迭代加密操作,混淆了明文的结构,提高了加密的安全性。
加密过程中涉及到扩展、置换、异或、S盒置换等操作,增加了破解的难度。
同时,DES密钥长度为56位,相对较短,存在被暴力破解的可能性。
DES算法广泛应用于各种网络通信、数据存储和传输中。
然而,由于DES密钥长度较短,安全性受到了质疑,逐渐被更安全的算法所替代,如AES算法。
C语言实现DES加密解密算法
C语言实现DES加密解密算法
最近几十年里,DES(Data Encryption Standard)算法的发展起到
了极其重要的作用。
Des算法是一种基于分组密码的算法。
算法将64位
的明文数据块按位分组成8个字节,每一组以8位为单位转换成一个64
位的密文数据块,采用16轮的分组加密,每次密码变化,保证加密强度。
本文详细介绍了DES算法的C语言实现,并分别介绍了加解密算法的实现
步骤以及DES加解密测试过程。
一、DES算法C语言实现
1.函数原型
DES算法的实现包括加密和解密函数,函数原型如下:
unsigned char* DesEncrypt(unsigned char *src, unsigned char
*key); // DES加密函数
unsigned char* DesDecrypt(unsigned char *src, unsigned char
*key); // DES解密函数
输入参数src是指明文源数据,key是加解密密钥,输出参数为一个
指向加解密结果的字符串指针。
2.加解密算法
(1)DES加密算法
DES加密算法步骤如下:
(i)初始置换:将64位明文块做一次IP置换得到L0R0。
(ii)迭代轮换:对L0R0经过16次迭代轮换后,最终结果为
L16R16
(iii)逆置换:L16R16进行逆置换得到64位密文。
(2)DES解密算法
DES解密算法步骤和DES加密算法步骤是一样的,只是将置换步骤改为逆置换,将轮换步骤改为逆轮换即可。
三、DES加解密测试
1.程序测试
在C语言编写完DES加解密算法之后。
des加密算法实验报告
des加密算法实验报告《des加密算法实验报告》摘要:本实验旨在研究和分析数据加密标准(Data Encryption Standard,DES)算法的原理和应用。
通过对DES算法的实验操作和结果分析,验证其在数据加密和解密过程中的可靠性和安全性。
一、实验目的1. 了解DES算法的基本原理和加密过程;2. 掌握DES算法的密钥生成和加密解密操作;3. 分析DES算法在数据加密中的应用和安全性。
二、实验原理DES算法是一种对称密钥加密算法,采用64位的明文和56位的密钥进行加密操作。
其基本加密过程包括初始置换、16轮的Feistel网络运算和最终置换。
在解密过程中,使用相同的密钥和逆向的Feistel网络运算来实现明文的恢复。
三、实验步骤1. 生成64位的明文和56位的密钥;2. 进行初始置换和16轮的Feistel网络运算;3. 进行最终置换并得到密文;4. 使用相同的密钥进行解密操作,恢复明文。
四、实验结果分析1. 经过实验操作,得到了正确的密文,并成功进行了解密操作;2. 分析了DES算法在数据加密中的安全性和可靠性,验证了其在信息安全领域的重要性和应用价值。
五、结论DES算法作为一种经典的对称密钥加密算法,具有较高的安全性和可靠性,在信息安全领域有着广泛的应用。
本实验通过对DES算法的实验操作和结果分析,验证了其在数据加密和解密过程中的有效性和实用性,为信息安全技术的研究和应用提供了重要的参考和借鉴。
综上所述,本实验对DES加密算法进行了深入研究和分析,得出了相应的实验结果和结论,为信息安全领域的相关研究和应用提供了有益的参考和借鉴。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
int IP_ANTEX[64]= { 40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31, 38, 6 }; //扩展矩阵 int EXTEND[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 }; //S盒 int S[8][4] [16]= { { {14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7}, {0, 15, 7, 4, 14, 2, 1 }, { {15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10}, {3, 13, 4, 7, 15, 2, 8, 14 }, { {10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8}, {13, 7, 0, 9, 3, 4, 6, 10 }, { { 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15}, {13, 8, 11, 5, 6, 15, 0, 3 { {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, }, { {4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1}, {13, 0, 11, 7, 4, 9, 1, 10 }, { {13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7}, {1, 15, 13, 8, 10, 3, 7, 4 }
}; int DIREX[32]= { 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10, 2, 8, 24, }; //左移移位表 int MOVELEFT[16]= { 1,1,2,2,2,2,2,2, 1,2,2,2,2,2,2,1 }; //压缩换位表2 int CutEX[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, 3 }; typedef char ElemType; ElemType subsec[16][48]; //Byte转bit int ByteToBit(ElemType ch,ElemType bit[8]) { for(int index = 7;index >= 0;index-) { bit[index] = (ch>>index)&1; //cout<<(int)bit[index]; } return 0; } //bit转Byte int BitToByte(ElemType bit[8],ElemType &ch) { ElemType tempch=0; ElemType temp } tempbit[7]=0; for(int index = 7;index >=0;index--) { tempch=tempch|(tempbit[index]<<(index)); } ch=tempch; //cout<<(char)tempch<<endl; return 0; }
//16轮加密迭代 void MoveLeft(ElemType C[28],ElemType D[28],ElemType L0[32],ElemType R0[32]) { 子密钥 ElemType Result[48]; //每轮异或结果 ElemType Sout[32];
//每轮S盒输出 ElemType DirOut[32]; //直接置换输出 ElemType RResult[32]; ElemType LResult[32]; ElemType ExpandMsg[48]; ElemType RResult[i]=R0[i]; } for(int i=0;i<16;i++) { if(MOVELEFT[i]==1) { for(int j=0;j<27;j++) { C[i]=C[i } C[27]=0; } else { for(int j=0;j<26;j++) { C[i]=C[i+2]; } C[26]=0; C[27]=0; } ExpandEX(RResult,ExpandMsg); GetCD48(C,D,Secret); for(int j=0;j<48;j++) { subsec[15-i][j]=Secret[j]; //获取界面的子密钥 }
XOR(ExpandMsg,Secret,Result); //S盒置换 getSOut(Result,Sout); //直接置换 DirExchange(Sout,DirOut); //与L进行异或 XORLR(DirOut,LResult,temp); for(int i=0;i<32;i++) { LResult[i]=RResult[i]; } for(int i=0;i<32;i++) { RResult[i]=temp[i]; } for(int i=0;i<32;i++) { L0[i]=LResult[i]; R0[i]=RResult[i]; } } /*cout<<"zuo" <<endl; for(int i=0;i<32;i++) { cout<<(int)LResult[i]; if((i+1)%8==0) { cout<<end } } cout<<"右边" <<endl; for(int i=0;i<32;i++) { cout<<(int)RResult[i]; if((i+1)%8==0) { cout<<endl; } }*/
6.源代码
// DES.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include "function.h" #include <iostream> #include<bitset> #include<
//置换矩阵 int IP_EX[64]= { 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, 62, 54, 46, 3 };
DES解密流程与加密流程基本相同,只不过在进行16轮迭代元算时,将 子密钥生成的 K的次序倒过来进行迭代运算 5、实验过程记录 在对DES算法有了清晰的认识后,编码过程中我将其分为几个关键部分 分别进行编码,最后将整个过程按顺序执行,即可完成DES的加密,代 码的主要几个函数如下: //Byte转为Bit ByteToBit(ElemType ch,ElemType bit[8]) //Bit转为Byte BitToByte(ElemType bit[8],ElemType &ch) //初始置换 InitialEX(ElemType Inorder[64],ElemType Disorder[64]) //终结置换 AntiEx(ElemType Disorder[64]) //扩展置换 ExpandEX(ElemType RightMsg[32],ElemType ExpandMsg[48]) //16轮迭代 加密 MoveLeft(ElemType C[28],ElemType D[28],ElemType L0[32],ElemType R0[32]) 3 //16轮迭代解密 mMoveLeft(ElemType C[28],ElemType D[28],ElemType L0[32],ElemType R0[32]) //生成48位子密钥 GetCD48(ElemType C[28],ElemType D[28],ElemType Secret[48]) //48位明 文与子密钥进行异或运算 XOR(ElemType ExpandMsg[48],ElemType Secret[48],ElemType Result[48]) //S 盒四位输出 getSOut(ElemType Result[48],ElemType Sout[32]) //直接置换 DirExchange(ElemType Sout[32],ElemType DirOut[32]) //Li与Ri进行抑或 运算 XORLR(ElemType DirOut[32],ElemType Left[32],ElemType Result[32]) 函数执行次序和调用关系关系如下:
1 实验一 1、实验题目 利用C/C++编程实现DES加密算法或MD5加密算法。我选择的是用 C++语言实现 DES的加密算法。 2、实验目的 通过编码实现DES算法或MD5算法,深入掌握算法的加密原理,理解其 实际应用 价值,同时要求用C/C++语言实现该算法,让我们从底层开始熟悉该算 法的实现过程 3、实验环境 操作系统:WIN7旗舰版 开发工具:Visual Studio 2010旗舰版 开发语言:C++ 4、实验原理 DES加密流程
LResult[j]=RResult[j]; } for(int j=0;j<32;j++) { RResult[j]=temp[j]; }