C语言实现DES算法实验报告分析
DES加密算法的简单实现实验报告
DES加密算法的简单实现实验报告一、实验目的本实验的主要目的是对DES加密算法进行简单的实现,并通过实际运行案例来验证算法的正确性和可靠性。
通过该实验可以让学生进一步了解DES算法的工作原理和加密过程,并培养学生对算法实现和数据处理的能力。
二、实验原理DES(Data Encryption Standard,数据加密标准)是一种对称密钥加密算法,它是美国联邦政府采用的一种加密标准。
DES算法使用了一个共享的对称密钥(也称为密钥),用于加密和解密数据。
它采用了分组密码的方式,在进行加密和解密操作时,需要将数据分成固定长度的数据块,并使用密钥对数据进行加密和解密。
DES算法主要由四个步骤组成:初始置换(Initial Permutation),轮函数(Round Function),轮置换(Round Permutation)和最终置换(Final Permutation)。
其中初始置换和最终置换是固定的置换过程,用于改变数据的顺序和排列方式。
轮函数是DES算法的核心部分,它使用了密钥和数据块作为输入,并生成一个与数据块长度相同的输出结果。
轮置换将轮函数的输出结果与前一轮的结果进行异或操作,从而改变数据的排列方式。
通过多轮的迭代运算,DES算法可以通过一个给定的密钥对数据进行高强度的加密和解密操作。
三、实验步骤2.初始置换:将输入数据按照一定的规则重新排列,生成一个新的数据块。
初始置换的规则通过查表的方式给出,我们可以根据规则生成初始置换的代码。
3.轮函数:轮函数是DES算法的核心部分,它使用轮密钥和数据块作为输入,并生成一个与数据块长度相同的输出结果。
在实际的算法设计和实现中,可以使用混合逻辑电路等方式来实现轮函数。
4.轮置换:轮置换将轮函数的输出结果与前一轮的结果进行异或操作,从而改变数据的排列方式。
轮置换的规则也可以通过查表的方式给出。
5.最终置换:最终置换与初始置换类似,将最后一轮的结果重新排列,生成最终的加密结果。
【精品】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密码算法综合实验报告
实
验
过
程
实验代码如下:
#include <iostream>
#include <fstream>
using namespace std;
FILE *file;
const static char rar[] = {
14, 17, 11, 24, 1, 5,
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,
35, 3, 43, 11, 51, 19, 59, 27,
34, 2, 42, 10, 50, 18, 58, 26,
33, 1, 41, 9, 49, 17, 57, 25 };
bool key[16][48]={0},/*rekey[16][48],*/
char key_in[8];
void ByteToBit(bool *Out,char *In,int bits)
tmp[i*4+3]=sbox[i][(hang+1)*16+lie]%2;
tmp[i*4+2]=(sbox[i][(hang+1)*16+lie]/2)%2;
tmp[i*4+1]=(sbox[i][(hang+1)*16+lie]/4)%2;
tmp[i*4]=(sbox[i][(hang+1)*16+lie]/8)%2; }
DES文件加密实验报告
DES文件加密实验报告一、DES算法简介DES是Data Encryption Standard(数据加密标准)的缩写。
它是由IBM公司研制的一种加密算法,美国国家标准局于1977年公布把它作为非机要部门使用的数据加密标准,二十年来,它一直活跃在国际保密通信的舞台上,扮演了十分重要的角色。
DES是一个分组加密算法,他以64位为分组对数据加密。
同时DES也是一个对称算法:加密和解密用的是同一个算法。
它的密匙长度是56位(因为每个第8 位都用作奇偶校验),密匙可以是任意的56位的数,而且可以任意时候改变。
其中有极少量的数被认为是弱密匙,但是很容易避开他们。
所以保密性依赖于密钥。
二、用C#实现DES文件加密指定文件,输入密钥来加密和解密数据。
DESCryptoServiceProvider基于对称加密算法。
Symmetricencryption 需要一个密钥和一个初始化向量(IV) 加密请。
要解密的数据,必须具有相同的密钥和IV。
使用的加密提供程序来获取encryptingobject (CreateEncryptor) 创建CryptoStream类的一个实例,现有输出文件流对象的构造函数的一部分。
要解密文件,执行以下步骤:创建一个方法,并命名该按钮DecryptFile.解密过程是类似于theencryption 进程,但是,DecryptFile过程从EncryptFile过程的两个主要区别。
而不是CreateEncryptor使用CreateDecryptor来创建CryptoStream对象,用于指定如何使用该对象。
解密的文本写入目标文件,CryptoStream对象是现在而不是目标流的来源。
三、运行环境可将DES文件加解密软件的可执行.exe文件直接在xp,win7等系统上运行。
四、实验结果1、开始界面2、打开要加密文件、输入密钥3、加密4、打开要解密文件、输入密钥5、解密五、主要算法代码public static void EncryptFile(string sInputFilename, string sOutputFilename, string sKey){FileStream fsInput = new FileStream(sInputFilename, FileMode.Open, FileAccess.Read);FileStream fsEncrypted = new FileStream(sOutputFilename, FileMode.Create, FileAccess.Write);DESCryptoServiceProvider DES = new DESCryptoServiceProvider();DES.Key = ASCIIEncoding.ASCII.GetBytes(sKey);DES.IV = ASCIIEncoding.ASCII.GetBytes(sKey);ICryptoTransform desencrypt = DES.CreateEncryptor();CryptoStream cryptostream = new CryptoStream(fsEncrypted, desencrypt, CryptoStreamMode.Write);byte[] bytearrayinput = new byte[fsInput.Length];fsInput.Read(bytearrayinput, 0, bytearrayinput.Length);cryptostream.Write(bytearrayinput, 0, bytearrayinput.Length);cryptostream.Close();fsInput.Close();fsEncrypted.Close();}public static void DecryptFile(string sInputFilename, string sOutputFilename, string sKey){try{DESCryptoServiceProvider DES = new DESCryptoServiceProvider();DES.Key = ASCIIEncoding.ASCII.GetBytes(sKey);DES.IV = ASCIIEncoding.ASCII.GetBytes(sKey);FileStream fsread = new FileStream(sInputFilename, FileMode.Open, FileAccess.Read);ICryptoTransform desdecrypt = DES.CreateDecryptor();CryptoStream cryptostreamDecr = new CryptoStream(fsread, desdecrypt, CryptoStreamMode.Read);StreamWriter fsDecrypted = new StreamWriter(sOutputFilename);fsDecrypted.Write(new StreamReader(cryptostreamDecr,Encoding.GetEncoding("GB2312")).ReadToEnd());fsDecrypted.Flush();fsDecrypted.Close();}catch (Exception e){MessageBox.Show(e.Message);}}。
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_加密解密算法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加密算法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加密算法的实现
实验报告DES加密算法的实现班级自动化学号:姓名:2016年11月13日星期日一、DES加密简述:DES算法是一种对称密码体制,由美国IBM公司在1972年研发。
其明文按64位进行分组,密钥长64位(包含8位校验位),分组后的明文组和56位的密钥按位替代或交换的方法形成密文组的加密方法。
二、DES的实现过程首先通过初始置换表IP对明文进行置换intIP_Table[64] = { 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,56,48,40,32,24,16,8,0,58,50,42,34,26,18,10,2,60,52,44,36,28,20,12,4,62,54,46,38,30,22,14,6};第一个57就是将明文中的第57个元素,放到第1的位置,然后把明文中第49个元素放到第2的位置,以此类推。
之后将换位后的输出分为两部分L0和R0,L0是输出的左32位,R0 是右32位。
intDES_IP_Transform(char data[64]){intcnt;char temp[64];for(cnt = 0; cnt< 64; cnt++){temp[cnt] = data[IP_Table[cnt]];}memcpy(data,temp,64);return 0;}之后加密函数,将R0通过位选择函数E置换,把本身是32位的R0扩充成48位,与生成的48位子密钥对应,按位运算。
intE_Table[48] = {31, 0, 1, 2, 3, 4,3, 4, 5, 6, 7, 8,7, 8,9,10,11,12,11,12,13,14,15,16,15,16,17,18,19,20,19,20,21,22,23,24,23,24,25,26,27,28,27,28,29,30,31, 0};intDES_E_Transform(char data[48]){intcnt;char temp[48];for(cnt = 0; cnt< 48; cnt++){temp[cnt] = data[E_Table[cnt]];}memcpy(data,temp,48);return 0;}然后,将扩充完的R0和子密钥K1进行模2加运算,得到48位的一个串,把这个串从左到右分为8组,每组6个字符。
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算法实验报告
《计算机安全技术》实验报告一、实验内容: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算法的实验报告
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数据加密算法
实验名称实验三加密编码--------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算法对实际的数据进行加密和解密来深刻了解DES的运行原理。
二、实验环境运行Windows或Linux操作系统的PC机,具有gcc(Linux)、VC(Windows)等C语言编译环境。
三、实验内容和步骤(1)使用附录提供的程序对一个文件进行加密和解密,程序代码和执行结果如下所示。
程序代码:#include "des.h"#include "stdio.h"int main(int argc, char *argv[]){unsigned char key[8]= { 'a','b','c','d','a','b','c','d' };des_key skey;des_setup(key,8,0,&skey);FILE *fd1;FILE *fd2;fd1=fopen("plaintext1.txt","rb");fd2=fopen("cipertext.txt","wb");int count=0;unsigned char p_buf[8];unsigned char c_buf[8];while(true){count=fread(p_buf,sizeof(unsigned char),8,fd1);if(count<8)for(int i=count;i<=7;i++)p_buf[i]='\0';des_ecb_encrypt(p_buf,c_buf,&skey);fwrite(c_buf,sizeof(unsigned char),8,fd2);if(count<8)break;count=0;}fclose(fd1);fclose(fd2);fd2=fopen("cipertext.txt","rb");网络安全实验报告学院专业班学号姓名成绩评定_______ 教师签名实验 1 题目对称密码算法DES 课程名称网络安全fd3=fopen("plaintext2.txt","wb");while(true){count=fread(p_buf,sizeof(unsigned char),8,fd2);if(count==0)break;des_ecb_decrypt(p_buf,c_buf,&skey);fwrite(c_buf,sizeof(unsigned char),8,fd3);count=0;}fclose(fd2);fclose(fd3);system("PAUSE");return 0;}程序执行结果:例如plaintext1.txt存放的明文为:加密后的密文为:解密后plaintext2.txt中的明文为:(2)使用附录提供的程序对输入的十六进制数加密(把输入的字符转化成整数。
C语言DES加密算法
云南大学软件学院School of Software, Yunnan University成绩学期: 2011秋季学期课程名称: 密码技术任课教师:学生姓名:学号:实验项目: 实验二 DES加密算法联系电话:电子邮件:完成提交时间:年月日密码技术实验报告实验项目:实验二,第2题实现DES对任意文件的加解密实验要求(内容)实现DES对任意文件的加解密,利用控制台对所有文件(中英文文本、符号甚至任意的文件)的加解密。
加解密形式如下:cipher -e/-d key inputfile outputfile说明:对于加密来说,输入文件名就是明文文件,对于解密来说,输入文件名就是密文文件,注意文件读取方式和控制文件结束控制台编程:int main(int argc, char *argv[ ])实验环境操作系统:win7编译环境:Microsoft Visual Studio 2010实现功能本次实验达到了题目的要求:实现了用DES实现控制台对任意文件的加解密,用键盘接收明文(密文)文件路径和密钥,然后再输入需要保存的密文(明文)文件路径,然后就可以把加解密后得到的密明文文件保存该路径下。
程序主要采取对数据的位操作的形式,把明密文文件中的内容以字节为单位读取,每次读取8个byte共65bits,然后使用标准DES的算法依次对读取的64bits明密文进出加解密处理。
主函数的操作也充分体现了程序的可操作性和健壮性,能够让用户自己选择相应的操作,比如加密、解密以及对程序的一些基本情况说明。
但是对文件的路径的输入有比较严格的格式约束。
如:盘符名:\\文件名.txt格式错误则会导致文件打开失败,不能进行加解密操作。
数据结构本次实验的程序较为复杂,涉及对位的操作。
实验过程中用到的主要数据结构为数组和文件型指针,在实验中我定义了2个文件型指针FILE *fp1,*fp2,其中一个指向明文文件,一个指向密文文件。
另外还定义了多个字符数组,如char Plainfpath[260]声明字符数组存储明文文件的文件路径,char Cipherfpath[260]声明字符数组存储密文文件的文件路径,char key[100]声明字符数组存储密钥。
DES算法实验报告-
DES算法实验报告-DES算法实验报告姓名:学号:班级:一、实验环境1.硬件配置:处理器(英特尔Pentium双核E5400 @ 2.70GHZ 内存:2G)2.使用软件:⑴操作系统:Windows XP 专业版32位SP3(DirectX 9.0C)⑵软件工具:Microsoft Visual C++ 6.0二、实验涉及的相关概念或基本原理1、加密原理DES 使用一个 56 位的密钥以及附加的 8 位奇偶校验位,产生最大 64 位的分组大小。
这是一个迭代的分组密码,使用称为 Feistel 的技术,其中将加密的文本块分成两半。
使用子密钥对其中一半应用循环功能,然后将输出与另一半进行“异或”运算;接着交换这两半,这一过程会继续下去,但最后一个循环不交换。
DES 使用 16 个循环,使用异或,置换,代换,移位操作四种基本运算。
三、实验内容1、关键代码⑴子密钥产生⑵F函数以及加密16轮迭代2、DES加密算法的描述及流程图⑴子密钥产生在DES算法中,每一轮迭代都要使用一个子密钥,子密钥是从用户输入的初始密钥产生的。
K是长度为64位的比特串,其中56位是密钥,8位是奇偶校验位,分布在8,16,24,32,40,48,56,64比特位上,可在8位中检查单个错误。
在密钥编排计算中只用56位,不包括这8位。
子密钥生成大致分为:置换选择1(PC-1)、循环左移、置换选择2(PC-2)等变换,分别产生16个子密钥。
DES解密算法与加密算法是相同的,只是子密钥的使用次序相反。
3、实验结果四、实验总结分析 通过这次实验,我发现DES 算法虽然并不复杂,但是真正实现起来,自己编程上还存在诸多不足,很多细微的知识点很容易就遗忘了,比如对与数组的应用也不是很扎实,数组下标和替换表之间存在1个位的偏差,如若没有理清逻辑关系,很容易出错,导致返工。
通过这次DES 加解密算法的实验,我对DES 的原理有了更深刻的认识,对初始变换,F 函数的扩展变换,S 盒,P 盒的混乱扩散效应有了更深的体会,经历了代码的编写后,我对DES 的16轮迭代的具体步骤,以及子密钥的产生更清晰明了,果然通过理论联系实际,才可以把零碎的知识点巩固加深。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
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中。
64 bit密钥去掉每个字节的最高位得到56 bit密钥输入,通过置换选择1变换得到0C和0D各28 bit,通过Zhihuan_1函数实现置换选择一。
Zhihuan_1函数输入为二进制密钥数组k[64],输出为C0和D0,将C0、D0分别储存在28位布尔数组C、D中。
函数采用查表方式生成C0和D0。
根据迭代的轮数确定C和D移位循环的位数,主程序中利用一个16位整形数组来存放每一次循环左移的位数。
循环左移通过XunHuan函数实现,函数输入为循环位数和长度为28的布尔数组(C或者D),函数运行一次只能改变一个布尔数组的值。
为了减低编程复杂度,程序使用串行方法,分两次进行C、D的移位。
每完成一次C和D的移位,进行一次置换选择二。
置换选择二利用zhihuan_2函数完成。
思想和Zhihuan_1函数类似。
zhihuan_2函数输入为移位后的C、D,zhihuan_2函数将圈子密钥存放在16*48的二维布尔数组kk[17][49] 中。
kk[i][48]表示第i圈的圈子密钥。
原理图如图1所示。
脱密(o=0时)需要将圈子密钥交换,此时可利用kk[0][49]充当中间变量,无需定义新的变量减少了系统开销。
1216图1 圈子密钥生成算法3、16圈迭代DES的每一圈迭代采用的是Feistel模型,先将初始置换后的明文mip数组分成L 和R两部分,先将R的内容放在等长的布尔数组T中,最后时需要将L的值赋为T。
之后进入F函数,F函数原理如图2。
图2 F函数原理图程序中的F函数输入有初始置换结果的右半部分R、圈子密钥kk、迭代圈数i。
输出保存在R中。
先将输入的R通过查表的方法进行E拓展,结果保存在48位布尔数组a中。
再将a与圈子密钥k按位模二加。
结果保存在a中。
接下来将a分成8组,分别进入8个S盒。
用for控制循环8次,每次操作选用6位二进制代码的开头一位和最后一位转化成十进制数,控制S盒的行数,再将6位二进制代码的中间四位转化成十进制数,控制S盒的列数。
进入第几个S盒有迭代圈数i确定。
取到S盒中的十进制数后,将它转化成二进制数,储存在32位布尔数组T中,在使用查表法完成P盒置换,最终结果保存在R中。
最后将L与R按位模二加,得到新的R,完成一次迭代。
4、逆初始置换16次迭代后,先将L16和R16连接起来,保存到64位布尔数组m中,m之前用于保存明文,这样减小了程序占用的空间。
另外,为了保证加脱密算法的一致性,迭代时最后一圈不需要交换L与R,但程序中为了简化编程复杂度,在迭代时仍然交换了L 与R。
所以在连接时需要再次交换L与R。
所以m的高32位应储存R,低32位应储存L。
逆初始置换原理同初始置换步骤,不再赘述。
四、取得的成果利用密钥201601211438FBCA对明文81623317加密,密文为6B217C871EAE79D2H结果如图3所示。
图3 DES加密结果图利用密钥201601211438FBCA对密文6B217C871EAE79D2脱密,明文为81623317。
结果如图4所示。
图4 DES脱密结果图变换不同明文及密钥,均可以正常加脱密。
在报告中不再罗列。
五、心得体会DES算法是一种分组密码算法,本人通过对一个明文分组的加脱密进行编程,耗时近一个月,独立完成了次算法的C++实现。
本人的程序不同于网上找的DES算法程序,网上的大多数程序的密文都是以ASCII码来输出的。
但是,这样输出的结果有很多乱码出现。
因为ASCII码只有在小范围内输出的结果是正常的字母、数字或者符号(从33至127),如果按ASCII输出乱码密文,脱密者就很难键入这些密文,只能通过复制粘贴进行。
而VC6.0的环境在控制台中很难进行复制操作,这样如果不借助文件,就很难完成密文的脱密。
而密文按16进制输出就不存在这个问题。
二进制串与ASCII码、16进制数之间的转化也是实验的难点之一。
C语言的课上没有讲过位运算的相关知识,本人只能通过除以二取余、查表等笨办法进行转化。
同样,密钥选用16进制也是一个道理,如果只用字符输入密钥,密钥的每八位就会局限在00100001(33)至01111111(127)范围之内,超过范围就无法用键盘进行输入密钥,这样破译者如果看到了加密程序源代码,相应的穷尽时间会减少。
通过本次编程,我发现我对C/C++语言的掌握还是不够,尤其是涉及到位运算。
我也会找机会自学这一部分内容。
六、附录程序代码:#include <iostream>using namespace std;void ToEr(char c[],bool k[]){int i,j;j=0;for(i=1;i<=16;i++){switch (c[i]){case '0':k[j++]=0;k[j++]=0;k[j++]=0;k[j++]=0;break;case '1':k[j++]=0;k[j++]=0;k[j++]=0;k[j++]=1;break;case '2':k[j++]=0;k[j++]=0;k[j++]=1;k[j++]=0;break;case '3':k[j++]=0;k[j++]=0;k[j++]=1;k[j++]=1;break;case '4':k[j++]=0;k[j++]=1;k[j++]=0;break; case '5':k[j++]=0;k[j++]=1;k[j++]=0;k[j++]=1;break; case '6':k[j++]=0;k[j++]=1;k[j++]=1;k[j++]=0;break; case '7':k[j++]=0;k[j++]=1;k[j++]=1;k[j++]=1;break; case '8':k[j++]=1;k[j++]=0;k[j++]=0;k[j++]=0;break; case '9':k[j++]=1;k[j++]=0;k[j++]=1;break; case 'A':k[j++]=1;k[j++]=0;k[j++]=1;k[j++]=0;break; case 'B':k[j++]=1;k[j++]=0;k[j++]=1;k[j++]=1;break; case 'C':k[j++]=1;k[j++]=1;k[j++]=0;k[j++]=0;break; case 'D':k[j++]=1;k[j++]=1;k[j++]=0;k[j++]=1;break; case 'E':k[j++]=1;k[j++]=1;k[j++]=1;k[j++]=0;break;case 'F':k[j++]=1;k[j++]=1;k[j++]=1;k[j++]=1;break;}}// for (i=0;i<64;i++) cout<<k[i];// cout<<endl;}void MtoEr(char asc[],bool m[]){int i,j,flag,f;int as[9];bool z[9]={0},t;for(i=1;i<=8;i++) as[i] = (int)asc[i];for (i=1;i<=8;i++){f=1;flag = 8 * (i-1);while(as[i]!=0){z[f] = as[i] % 2;as[i] /= 2;f++;}// for(j=1;j<=8;j++) cout<<z[j];// cout<<endl;for(j=1;j<=4;j++) {t = z[j];z[j] = z[9-j];z[9-j] = t;}// z[1] = 0;for(j=1;j<=8;j++) m[flag+j] = z[j];for(j=1;j<=8;j++) z[j]=0;}// for(j=1;j<=64;j++) cout<<m[j];// cout<<endl;}void IP(bool m[],bool mip[]){int ip[64]={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,56, 48, 40, 32, 24, 16, 8, 0,58, 50, 42, 34, 26, 18, 10, 2,60, 52, 44, 36, 28, 20, 12, 4,62, 54, 46, 38, 30, 22, 14, 6};for (int i=1;i<=64;i++) mip[i]=m[ip[i-1]+1];}void IP2(bool m[],bool mip[]){int ip[64]={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,32, 0, 40, 8, 48, 16, 56, 24};for (int i=1;i<=64;i++) mip[i]=m[ip[i-1]+1]; }void Zhihuan_1(bool k[],bool C[],bool D[]){int a[28]={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};int b[28]={63,55,47,39,31,23,15,7,62,54,46,38,30,22,14,6,61,53,45,37,29,21,13,5,28,20,12,4};int i;for(i=1;i<=28;i++) C[i]=k[a[i-1]];for(i=1;i<=28;i++) D[i]=k[b[i-1]];// for(i=1;i<=28;i++) cout<<C[i]; cout<<endl;// for(i=1;i<=28;i++) cout<<D[i]; cout<<endl;}void zhihuan_2(bool C[],bool D[],bool k[][49],int q) {int a[48]={13,16,10,23,0,4,2,27,14,5,20,9,22,18,11,3,25,7,15,6,26,19,12,1,40,51,30,36,46,54,29,39,50,44,32,47,43,48,38,55,33,52,45,41,49,35,28,31};int i;bool T[57];for (i=1;i<=56;i++){if(i<=28) T[i] = C[i];else T[i] = D[i-28];}for(i=1;i<=48;i++)k[q+1][i]=T[a[i-1]+1];// for (i=1;i<=48;i++) cout<<k[q+1][i]; cout<<endl; }void XunHuan(int x,bool C[]){int i;bool T[29];for(i=1;i<29;i++) T[i] = C[(i+x)%28+1];for(i=1;i<29;i++) C[i] = T[i];}void F(bool R[],bool kk[][49],int x){int E[48]={31, 0, 1, 2, 3, 4,3, 4, 5, 6, 7, 8,7, 8, 9, 10, 11, 12,11, 12, 13, 14, 15, 16,15, 16, 17, 18, 19, 20,19, 20, 21, 22, 23, 24,23, 24, 25, 26, 27, 28,27, 28, 29, 30, 31, 0};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,10, 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,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} },{{ 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,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}}};int i,j,p,a1,a2,k[8];bool a[49],b[33];for (i=1;i<=48;i++) a[i] = R[E[i-1]+1];// for (i=1;i<=48;i++) cout<<a[i];for (i=1;i<=48;i++) a[i]^= kk[x][i];// for (i=1;i<=48;i++) cout<<a[i];p=1;for (i=0;i<8;i++){a1 = a[p]*2+a[p+5];//左右两位换成十进制数a2 = a[p+1]*8+a[p+2]*4+a[p+3]*2+a[p+4]; //中间4位换成十进制数// cout<<a1<<endl;// cout<<a2<<endl;p += 6;k[i] = S[i][a1][a2];// cout<<k[i]<<endl;}p=1;for (i=0;i<8;i++){switch (k[i]){case 0: b[p++] = 0;b[p++] = 0;b[p++] = 0;b[p++] = 0;break;case 1: b[p++] = 0;b[p++] = 0;b[p++] = 0;b[p++] = 1;break;case 2: b[p++] = 0;b[p++] = 0;b[p++] = 1;b[p++] = 0;break;case 3: b[p++] = 0;b[p++] = 0;b[p++] = 1;b[p++] = 1;break;case 4: b[p++] = 0;b[p++] = 1;b[p++] = 0;b[p++] = 0;break;case 5: b[p++] = 0;b[p++] = 1;b[p++] = 0;b[p++] = 1;break;case 6: b[p++] = 0;b[p++] = 1;b[p++] = 1;b[p++] = 0;break; case 7: b[p++] = 0;b[p++] = 1;b[p++] = 1;b[p++] = 1;break; case 8: b[p++] = 1;b[p++] = 0;b[p++] = 0;b[p++] = 0;break; case 9: b[p++] = 1;b[p++] = 0;b[p++] = 0;b[p++] = 1;break; case 10: b[p++] = 1;b[p++] = 0;b[p++] = 1;b[p++] = 0;break; case 11: b[p++] = 1;b[p++] = 0;b[p++] = 1;b[p++] = 1;break; case 12: b[p++] = 1;b[p++] = 1;b[p++] = 0;b[p++] = 0;break; case 13: b[p++] = 1;b[p++] = 1;b[p++] = 0;b[p++] = 1;break;case 14: b[p++] = 1;b[p++] = 1;b[p++] = 1;b[p++] = 0;break;case 15: b[p++] = 1;b[p++] = 1;b[p++] = 1;b[p++] = 1;break;}}bool T[33];for(i=1;i<=32;i++) T[i]=b[i];int P[32]={15,6,19,20,28,11,27,16,0,14,22,25,4,17,30,9,1,7,23,13,31,26,2,8,18,12,29,5,21,10,3,24};for(i=1;i<=32;i++) R[i]=T[P[i-1]+1];}void main(){ char c[17],asc[9];int i,j,mout[17];bool k[65],kk[17][49],C[29],D[29],m[65],mip[65],L[33],R[33],T[33]; //k存放二进制密钥,kk存放16圈的圈子密钥,m存放明文,mip存放明文初始变换后int z[16]={1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};int o; //C、D存放圈子密钥生产算法的左右两个部分。