DES加密算法文档
联邦数据加密标准(des)算法数据加密
文章标题:深入探讨联邦数据加密标准(DES)算法数据加密随着信息化时代的不断发展,数据安全问题变得愈发突出。
在处理机密信息时,保护数据的安全性至关重要。
而联邦数据加密标准(DES)算法作为一种被广泛应用的数据加密方式,其加密原理和应用领域备受关注。
本文将从深度和广度的角度,全面探讨DES算法的数据加密,让我们共同深入理解这一重要技术。
一、理解DES算法1.1 DES算法的基本概念在加密领域,DES算法是一种对称密钥加密算法,它使用相同的密钥对数据进行加密和解密。
其基本原理是通过将明文按照密钥进行置换和替换运算,生成密文,从而实现数据的加密。
1.2 DES算法的加密过程DES算法的加密过程包括初始置换、16轮迭代运算和终结置换。
在初始置换阶段,明文经过一系列置换操作后得到L0和R0,然后进行16轮迭代运算,最终得到L16和R16。
通过终结置换生成密文,完成加密过程。
1.3 DES算法的密钥管理DES算法的密钥长度为56位,但采用64位的密钥空间,在加密和解密中对密钥进行了置换和选择操作。
密钥管理是DES算法中至关重要的一环,合理的密钥管理可以有效提升数据的安全性。
二、DES算法的应用领域2.1 网络数据传输安全在网络数据传输安全领域,DES算法被广泛应用于加密通信协议、虚拟专用网络等方面,保障了网络数据的安全传输和交换。
2.2 数据存储安全在数据存储领域,DES算法可用于对存储在磁盘上的数据进行加密保护,防止未经授权的访问和篡改。
2.3 金融交易安全在金融领域,DES算法可用于加密银行卡交易数据、电子支付信息等,保障了用户资金安全和交易隐私。
三、对DES算法的个人观点和理解在我看来,DES算法作为一种经典的对称密钥加密算法,在数据安全领域的应用前景广阔。
然而,随着计算机算力的不断提升,DES算法的安全性逐渐受到挑战,其密钥长度较短、加密速度较慢等问题也亟待解决。
针对DES算法的不足之处,我们可以结合其他加密算法,如AES算法、RSA算法等,构建更为安全和高效的数据加密方案。
des算法c++实现--文档
高级编程DES加密算法C++程序实现姓名:***学号:*********专业:电路与系统一、DES算法简要介绍DES算法为密码体制中的对称密码体制,又被成为美国数据加密标准,是1972年美国IBM公司研制的对称密码体制加密算法。
明文按64位进行分组, 密钥长64位,密钥事实上是56位参与DES运算(第8、16、24、32、40、48、56、64位是校验位,使得每个密钥都有奇数个1)分组后的明文组和56位的密钥按位替代或交换的方法形成密文组的加密方法。
DES加密算法特点:分组比较短、密钥太短、密码生命周期短、运算速度较慢。
DES工作的基本原理是,其入口参数有三个:key、data、mode。
key为加密解密使用的密钥,data为加密解密的数据,mode为其工作模式。
当模式为加密模式时,明文按照64位进行分组,形成明文组,key用于对数据加密,当模式为解密模式时,key用于对数据解密。
实际运用中,密钥只用到了64位中的56位,这样才具有高的安全性。
DES算法把64位的明文输入块变为64位的密文输出块,它所使用的密钥也是64位。
DES算法具有极高安全性,到目前为止,除了用穷举搜索法对DES算法进行攻击外,还没有发现更有效的办法。
而56位长的密钥的穷举空间为256,这意味着如果一台计算机的速度是每一秒种检测一百万个密钥,则它搜索完全部密钥就需要将近2285年的时间,可见,这是难以实现的,当然,随着科学技术的发展,DES算法加密的明文已经被高速计算机破解,但是DES目前仍然得到广泛的应用,在某些场合仍然发挥余热。
12二、C++实现简要介绍2.1 密钥生成 2.1.1 取得密钥从用户处取得一个64位(本文如未特指,均指二进制位))长的密码key ,在程序实现中,用一9位字符数组存放用户输入的八个字符,然后将字符数组转换成二进制形式存储在一长度为64的int 型数组当中。
程序流程图如图表1示。
去除64位密码中作为奇偶校验位的第8、16、24、32、40、48、56、64位,剩下的56位作为有效输入密钥。
des加密算法实验报告
DES加密算法实验报告1. 引言DES(Data Encryption Standard)是一种对称密码算法,于1977年被美国联邦信息处理标准(FIPS)确定为联邦标准。
DES加密算法采用分组密码的思想,将明文按照64位分为一组,经过一系列的置换、替代和迭代操作,最终输出加密后的密文。
本实验旨在通过对DES加密算法的实际操作,深入理解DES的工作原理和加密过程。
2. 实验步骤2.1. 密钥生成DES加密算法的核心在于密钥的生成。
密钥生成过程如下:1.将64位的初始密钥根据置换表进行置换,生成56位密钥。
2.将56位密钥分为两个28位的子密钥。
3.对两个子密钥进行循环左移操作,得到循环左移后的子密钥。
4.将两个循环左移后的子密钥合并,并根据压缩置换表生成48位的轮密钥。
2.2. 加密过程加密过程如下:1.将64位的明文按照初始置换表进行置换,得到置换后的明文。
2.将置换后的明文分为左右两部分L0和R0,每部分32位。
3.进行16轮迭代操作,每轮操作包括以下步骤:–将R(i-1)作为输入,经过扩展置换表扩展为48位。
–将扩展后的48位数据与轮密钥Ki进行异或操作。
–将异或结果按照S盒进行替代操作,得到替代后的32位数据。
–对替代后的32位数据进行置换,得到置换后的32位数据。
–将置换后的32位数据与L(i-1)进行异或操作,得到Ri。
–将R(i-1)赋值给L(i)。
4.将最后一轮迭代后得到的数据合并为64位数据。
5.对合并后的64位数据进行逆置换,得到加密后的64位密文。
3. 实验结果对于给定的明文和密钥,进行DES加密实验,得到加密后的密文如下:明文:0x0123456789ABCDEF 密钥:0x133457799BBCDFF1密文:0x85E813540F0AB4054. 结论本实验通过对DES加密算法的实际操作,深入理解了DES加密算法的工作原理和加密过程。
DES加密算法通过对明文的置换、替代和迭代操作,混淆了明文的结构,使得密文的产生与密钥相关。
des算法标准代码
des算法标准代码一、概述DES(数据加密标准)是一种常用的对称加密算法,它使用64位的密钥对数据进行加密和解密。
本标准代码文档旨在提供DES算法的完整实现,以便读者了解其工作原理和实现细节。
二、算法描述1. 密钥生成:DES算法使用一个56位的密钥,通过一系列复杂的算法将其转换为64位的数据。
2. 加密过程:加密过程包括三个步骤:初始置换、分组和迭代。
在迭代过程中,每个分组被替换为新的分组,并使用密钥进行置换和移位操作。
3. 解密过程:解密过程与加密过程类似,但使用与加密时相反的置换和移位操作。
三、代码实现以下是一个简单的Python实现示例:```pythonfrom Crypto.Cipher import DESfrom Crypto.Util.Padding import pad, unpadfrom binascii import hexlify, unhexlifyimport random# 密钥生成函数def generate_key(bit_length=8):key = [0]*64for i in range(bit_length//8):random.shuffle(key[:8]) # 使用随机数填充8字节密钥的一部分 if i != bit_length//8-1: # 最后一位用校验位替代,所以不算进bit_length长度中random.shuffle(key[8:]) # 对剩余字节打乱顺序,以保护剩余部分的秘密性return key.tolist() # 转换为列表便于序列化处理# DES加密/解密函数def des_encrypt(data, key):des = DES.new(key, DES.MODE_ECB) # 使用ECB模式进行加密padded_data = pad(data.encode(), DES.block_size) # 对数据进行填充处理encrypted_data = des.encrypt(padded_data) # 进行加密操作return encrypted_data.hex() # 将加密结果转换为十六进制字符串方便查看def des_decrypt(encrypted_data, key):des = DES.new(key, DES.MODE_ECB) # 使用ECB模式进行解密操作decrypted_data = des.decrypt(unhexlify(encrypted_data)) # 进行解密操作,并将结果解码为原始数据return unpad(decrypted_data).decode() # 将解密结果进行去填充处理,并解码为原始字符串返回```四、使用示例以下是一个简单的使用示例:```python# 生成随机密钥,这里假设使用长度为8字节的密钥,根据实际情况进行修改即可key = generate_key()print("Generated key: {}".format(hexlify(key)))# 要加密的数据(这里使用字符串“Hello World”作为示例)data = "Hello World"print("Original data: {}".format(data))encrypted_data = des_encrypt(data, key) # 对数据进行加密操作,并输出加密结果(十六进制字符串)print("Encrypted {}".format(encrypted_data))decrypted_data = des_decrypt(encrypted_data, key) # 对加密结果进行解密操作,并输出解密结果(原始字符串)print("Decrypted {}".format(decrypted_data))```请注意,这只是一个简单的示例代码,用于演示DES算法的实现和基本用法。
电脑文档加密的几种方法
电脑文档加密的几种方法
电脑文档加密是一种用于保护私有信息安全的行为,目前也是越来越多企业与个人都
采用的安全保护手段。
电脑文档加密有多种方法,本文将介绍以下几种方法。
一、DES算法加密
DES算法(Data Encryption Standard)是一种对称加密算法,DES算法只有一个密钥,可以用于加密和解密同一数据。
DES算法对于电脑文档的加密很有效,特别是对重要
文档的加密,可以很好的保护文档的安全。
AES算法(Advanced Encryption Standard)是美国国家标准局发布的一种对称加密
算法。
AES算法使用长度可变的128位、192位或256位来代表密钥,比DES算法更为安
全强大,能够更快速、更安全地对电脑文档进行加密。
RSA算法(Rivest-Shamir-Adleman)是一种非对称加密算法,RSA算法有两个密钥,
然后用公钥进行加密,再使用私钥进行解密,非常安全,RSA算法可用于网上交易的安全,也可用于电脑文档的加密,特别是比较重要的文档。
四、PGP算法加密
PGP算法(Pretty Good Privacy)是由美国知名企业Symantec发布的电子加密标准,PGP算法可以实现文件的加密和解密,再搭配随机验证,可以将文件传输过程中的内容完
整性保持完整,在电脑文档加密中很安全。
以上就是电脑文档加密的几种常用方法,采用不同的方法可以达到不同标准的安全性能,对于对文档安全要求较高的情况,应该选择比较安全的加密算法。
des加密算法
des加密算法des加密算法是⼀种对称加密算法,通常要求8字节对齐,如果不满⾜8字节,则补全到8字节的整数倍,通常的做法是缺⼏补⼏,⽐如21字节的内容,则需要补三个3./********************************************************** des.h* ⽤户使⽤des算法头⽂件**********************************************************/#ifndef _OPENDESS_H_#define _OPENDESS_H_#ifdef __cplusplusextern "C" {#endif//ab\0defg//⽤户使⽤的函数int DesEnc(unsigned char *pInData,int nInDataLen,unsigned char *pOutData,int *pOutDataLen);//⽤户使⽤函数des解密int DesDec(unsigned char *pInData,int nInDataLen,unsigned char *pOutData,int *pOutDataLen);#ifdef __cplusplus}#endif#endif/******************************************************** des.c* common des......*******************************************************/#include <stdlib.h>#include <string.h>#include <stdio.h>#include "des.h"/*********************************************************data type definition for Des;**********************************************************/#define EN0 0#define DE1 1#define DES_KEYBYTES 128#define DES_KEYLONGS 32#define DES_BLOCKLEN 8typedef struct {unsigned char ek[DES_KEYBYTES];int ekLen;unsigned char dk[DES_KEYBYTES];int dkLen;unsigned char CbcCtx[DES_BLOCKLEN];} DES_CTX;typedef struct {unsigned char ek1[DES_KEYBYTES];int ek1Len;unsigned char dk1[DES_KEYBYTES];int dk1Len;unsigned char ek2[DES_KEYBYTES];int ek2Len;unsigned char dk2[DES_KEYBYTES];int dk2Len;unsigned char CbcCtx[DES_BLOCKLEN];//int IsFirstBlock;} DES3_CTX;static unsigned char pc1[56] = {56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17,9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35,62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21,13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3 };static unsigned char pc2[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 };static unsigned short bytebit[8] = {0200,0100,040,020,010,04,02,01 };static unsigned char totrot[16] = {1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28}; static unsigned long bigbyte[24] = {0x800000L, 0x400000L, 0x200000L, 0x100000L,0x80000L, 0x40000L, 0x20000L, 0x10000L,0x8000L, 0x4000L, 0x2000L, 0x1000L,0x800L, 0x400L, 0x200L, 0x100L,0x80L, 0x40L, 0x20L, 0x10L,0x8L, 0x4L, 0x2L, 0x1L };//insert digitsstatic unsigned long SP1[64] ={0x01010400l,0x00000000l,0x00010000l,0x01010404l,0x01010004l,0x00010404l,0x00000004l,0x00010000l,0x00000400l,0x01010400l,0x01010404l,0x00000400l,0x01000404l,0x01010004l,0x01000000l,0x00000004l,0x00000404l,0x01000400l,0x01000400l,0x00010400l,0x00010400l,0x01010000l,0x01010000l,0x01000404l,0x00010004l,0x01000004l,0x01000004l,0x00010004l,0x00000000l,0x00000404l,0x00010404l,0x01000000l,0x00010000l,0x01010404l,0x00000004l,0x01010000l,0x01010400l,0x01000000l,0x01000000l,0x00000400l,0x01010004l,0x00010000l,0x00010400l,0x01000004l,0x00000400l,0x00000004l,0x01000404l,0x00010404l,0x01010404l,0x00010004l,0x01010000l,0x01000404l,0x01000004l,0x00000404l,0x00010404l,0x01010400l,0x00000404l,0x01000400l,0x01000400l,0x00000000l,0x00010004l,0x00010400l,0x00000000l,0x01010004l };static unsigned long SP2[64]={0x80108020l,0x80008000l,0x00008000l,0x00108020l,0x00100000l,0x00000020l,0x80100020l,0x80008020l,0x80000020l,0x80108020l,0x80108000l,0x80000000l,0x80008000l,0x00100000l,0x00000020l,0x80100020l,0x00108000l,0x00100020l,0x80008020l,0x00000000l,0x80000000l,0x00008000l,0x00108020l,0x80100000l,0x00100020l,0x80000020l,0x00000000l,0x00108000l,0x00008020l,0x80108000l,0x80100000l,0x00008020l,0x00000000l,0x00108020l,0x80100020l,0x00100000l,0x80008020l,0x80100000l,0x80108000l,0x00008000l,0x80100000l,0x80008000l,0x00000020l,0x80108020l,0x00108020l,0x00000020l,0x00008000l,0x80000000l,0x00008020l,0x80108000l,0x00100000l,0x80000020l, 0x00100020l,0x80008020l,0x80000020l,0x00100020l, 0x00108000l,0x00000000l,0x80008000l,0x00008020l, 0x80000000l,0x80100020l,0x80108020l,0x00108000l }; static unsigned long SP3[64]={0x00000208l,0x08020200l,0x00000000l,0x08020008l, 0x08000200l,0x00000000l,0x00020208l,0x08000200l, 0x00020008l,0x08000008l,0x08000008l,0x00020000l, 0x08020208l,0x00020008l,0x08020000l,0x00000208l, 0x08000000l,0x00000008l,0x08020200l,0x00000200l, 0x00020200l,0x08020000l,0x08020008l,0x00020208l, 0x08000208l,0x00020200l,0x00020000l,0x08000208l, 0x00000008l,0x08020208l,0x00000200l,0x08000000l, 0x08020200l,0x08000000l,0x00020008l,0x00000208l, 0x00020000l,0x08020200l,0x08000200l,0x00000000l, 0x00000200l,0x00020008l,0x08020208l,0x08000200l, 0x08000008l,0x00000200l,0x00000000l,0x08020008l, 0x08000208l,0x00020000l,0x08000000l,0x08020208l, 0x00000008l,0x00020208l,0x00020200l,0x08000008l, 0x08020000l,0x08000208l,0x00000208l,0x08020000l, 0x00020208l,0x00000008l,0x08020008l,0x00020200l }; static unsigned long SP4[64]={0x00802001l,0x00002081l,0x00002081l,0x00000080l, 0x00802080l,0x00800081l,0x00800001l,0x00002001l, 0x00000000l,0x00802000l,0x00802000l,0x00802081l, 0x00000081l,0x00000000l,0x00800080l,0x00800001l, 0x00000001l,0x00002000l,0x00800000l,0x00802001l, 0x00000080l,0x00800000l,0x00002001l,0x00002080l, 0x00800081l,0x00000001l,0x00002080l,0x00800080l, 0x00002000l,0x00802080l,0x00802081l,0x00000081l, 0x00800080l,0x00800001l,0x00802000l,0x00802081l, 0x00000081l,0x00000000l,0x00000000l,0x00802000l, 0x00002080l,0x00800080l,0x00800081l,0x00000001l, 0x00802001l,0x00002081l,0x00002081l,0x00000080l, 0x00802081l,0x00000081l,0x00000001l,0x00002000l, 0x00800001l,0x00002001l,0x00802080l,0x00800081l, 0x00002001l,0x00002080l,0x00800000l,0x00802001l, 0x00000080l,0x00800000l,0x00002000l,0x00802080l }; static unsigned long SP5[64]={0x00000100l,0x02080100l,0x02080000l,0x42000100l, 0x00080000l,0x00000100l,0x40000000l,0x02080000l, 0x40080100l,0x00080000l,0x02000100l,0x40080100l, 0x42000100l,0x42080000l,0x00080100l,0x40000000l, 0x02000000l,0x40080000l,0x40080000l,0x00000000l, 0x40000100l,0x42080100l,0x42080100l,0x02000100l, 0x42080000l,0x40000100l,0x00000000l,0x42000000l, 0x02080100l,0x02000000l,0x42000000l,0x00080100l, 0x00080000l,0x42000100l,0x00000100l,0x02000000l, 0x40000000l,0x02080000l,0x42000100l,0x40080100l, 0x02000100l,0x40000000l,0x42080000l,0x02080100l, 0x40080100l,0x00000100l,0x20000000l,0x42080000l, 0x42080100l,0x00080100l,0x42000000l,0x42080100l, 0x02080000l,0x02000100l,0x40000100l,0x00080000l, 0x00080100l,0x02000100l,0x40000100l,0x00080000l, 0x00000000l,0x40080000l,0x02080100l,0x40000100l }; static unsigned long SP6[64]={0x20000010l,0x20400000l,0x00004000l,0x20404010l, 0x20400000l,0x00000010l,0x20404010l,0x00400000l, 0x20004000l,0x00404010l,0x00400000l,0x20000010l, 0x00400010l,0x20004000l,0x20000000l,0x00004010l,0x00000000l,0x00400010l,0x20004010l,0x00004000l,0x00404000l,0x20004010l,0x00000010l,0x20400010l,0x20400010l,0x00000000l,0x00404010l,0x20404000l,0x00004010l,0x00404000l,0x20404000l,0x20000000l,0x20004000l,0x00000010l,0x20400010l,0x00404000l,0x20404010l,0x00400000l,0x00004010l,0x20000010l,0x00400000l,0x20004000l,0x20000000l,0x00004010l,0x20000010l,0x20404010l,0x00404000l,0x20400000l,0x00404010l,0x20404000l,0x00000000l,0x20400010l,0x00000010l,0x00004000l,0x20400000l,0x00404010l,0x00004000l,0x00400010l,0x20004010l,0x00000000l,0x20404000l,0x20000000l,0x00400010l,0x20004010l };static unsigned long SP7[64] = {0x00200000L, 0x04200002L, 0x04000802L, 0x00000000L,0x00000800L, 0x04000802L, 0x00200802L, 0x04200800L,0x04200802L, 0x00200000L, 0x00000000L, 0x04000002L,0x00000002L, 0x04000000L, 0x04200002L, 0x00000802L,0x04000800L, 0x00200802L, 0x00200002L, 0x04000800L,0x04000002L, 0x04200000L, 0x04200800L, 0x00200002L,0x04200000L, 0x00000800L, 0x00000802L, 0x04200802L,0x00200800L, 0x00000002L, 0x04000000L, 0x00200800L,0x04000000L, 0x00200800L, 0x00200000L, 0x04000802L,0x04000802L, 0x04200002L, 0x04200002L, 0x00000002L,0x00200002L, 0x04000000L, 0x04000800L, 0x00200000L,0x04200800L, 0x00000802L, 0x00200802L, 0x04200800L,0x00000802L, 0x04000002L, 0x04200802L, 0x04200000L,0x00200800L, 0x00000000L, 0x00000002L, 0x04200802L,0x00000000L, 0x00200802L, 0x04200000L, 0x00000800L,0x04000002L, 0x04000800L, 0x00000800L, 0x00200002L };static unsigned long SP8[64] = {0x10001040L, 0x00001000L, 0x00040000L, 0x10041040L,0x10000000L, 0x10001040L, 0x00000040L, 0x10000000L,0x00040040L, 0x10040000L, 0x10041040L, 0x00041000L,0x10041000L, 0x00041040L, 0x00001000L, 0x00000040L,0x10040000L, 0x10000040L, 0x10001000L, 0x00001040L,0x00041000L, 0x00040040L, 0x10040040L, 0x10041000L,0x00001040L, 0x00000000L, 0x00000000L, 0x10040040L,0x10000040L, 0x10001000L, 0x00041040L, 0x00040000L,0x00041040L, 0x00040000L, 0x10041000L, 0x00001000L,0x00000040L, 0x10040040L, 0x00001000L, 0x00041040L,0x10001000L, 0x00000040L, 0x10000040L, 0x10040000L,0x10040040L, 0x10000000L, 0x00040000L, 0x10001040L,0x00000000L, 0x10041040L, 0x00040040L, 0x10000040L,0x10040000L, 0x10001000L, 0x10001040L, 0x00000000L,0x10041040L, 0x00041000L, 0x00041000L, 0x00001040L,0x00001040L, 0x00040040L, 0x10000000L, 0x10041000L };void deskey(unsigned char *key,short edf, unsigned long *kn);void cookey(register unsigned long *raw1, unsigned long *dough);//void cpkey(register unsigned long *into);//void usekey(register unsigned long *from);//void des(unsigned char *inblock,unsigned char *outblock);void scrunch(register unsigned char *outof, register unsigned long *into); void unscrun(register unsigned long *outof, register unsigned char *into); void desfunc(register unsigned long *block,register unsigned long *keys); /***************** DES Function *****************/unsigned long OPENCOMM_DesExpandEncKey(unsigned char *pbDesKey,unsigned long ulDesKeyLen,unsigned char *pbDesEncKey,unsigned long *ulDesEncKeyLen);unsigned long OPENCOMM_DesExpandDecKey(unsigned char *pbDesKey,unsigned long ulDesKeyLen,unsigned char *pbDesDecKey,unsigned long *ulDesDecKeyLen);unsigned long OPENCOMM_DesEncRaw(unsigned char *pbDesEncKey,unsigned long ulDesEncKeyLen,unsigned char *pbInData,unsigned long ulInDataLen,unsigned char *pbOutData,unsigned long *ulOutDataLen);unsigned long OPENCOMM_DesDecRaw(unsigned char *pbDesDecKey,unsigned long ulDesDecKeyLen,unsigned char *pbInData,unsigned long ulInDataLen,unsigned char *pbOutData,unsigned long *ulOutDataLen);int myic_DESDecrypt(unsigned char *pDesKey,int nDesKeyLen,unsigned char *pInData,int nInDataLen,unsigned char *pOutData,int *pOutDataLen);int myic_DESEncrypt(unsigned char *pDesKey,int nDesKeyLen,unsigned char *pInData,int nInDataLen,unsigned char *pOutData,int *pOutDataLen);void deskey(unsigned char *key,short edf, unsigned long *kn){register int i, j, l, m, n;unsigned long pc1m[56],pcr[56];for ( j = 0; j < 56; j++ ){l = pc1[j];m = l & 07;pc1m[j] = (((unsigned long) key[l >> 3] & (unsigned long)bytebit[m] ) ? 1:0); }for ( i = 0;i < 16; i++){if ( edf == DE1 ) m = (15 - i) << 1;else m = i << 1;n = m + 1;kn[m] = kn[n] = 0L;for ( j = 0; j < 28; j++ ){l = j + totrot[i];if ( l < 28 ) pcr[j] = pc1m[l];else pcr[j] = pc1m[l-28];}for (j = 28; j < 56; j++ ){l = j + totrot[i];if ( l < 56 ) pcr[j] = pc1m[l];else pcr[j] = pc1m[l-28];}for ( j = 0; j < 24; j++ ){if ( pcr[pc2[j]] ) kn[m] |= bigbyte[j];if ( pcr[pc2[j+24]] ) kn[n] |= bigbyte[j];}}return;}void cookey(register unsigned long *raw1, unsigned long *dough){register unsigned long *cook,*raw0;register int i;cook = dough;for ( i = 0; i < 16; i++, raw1++ ) {raw0 = raw1++;*cook = (*raw0 & 0x00fc0000L) << 6;*cook |= (*raw0 & 0x00000fc0L) << 10;*cook |= (*raw1 & 0x00fc0000L) >> 10;*cook++ |= (*raw1 & 0x00000fc0L) >> 6;*cook = (*raw0 & 0x0003f000L) << 12;*cook |= (*raw0 & 0x0000003fL) << 16;*cook |= (*raw1 & 0x0003f000L) >> 4;*cook++ |= (*raw1 & 0x0000003fL);}return;}void scrunch(register unsigned char *outof, register unsigned long *into) {*into = (*outof++ & 0xffL) << 24;*into |= (*outof++ & 0xffL) << 16;*into |= (*outof++ & 0xffL) << 8;*into++ |= (*outof++ & 0xffL);*into = (*outof++ & 0xffL) << 24;*into |= (*outof++ & 0xffL) << 16;*into |= (*outof++ & 0xffL) << 8;*into++ |= (*outof & 0xffL);return;}void unscrun(register unsigned long *outof, register unsigned char *into) {*into++ = (unsigned char)((*outof >> 24) & 0xffL);*into++ = (unsigned char)((*outof >> 16) & 0xffL);*into++ = (unsigned char)((*outof >> 8) & 0xffL);*into++ = (unsigned char)( *outof++ & 0xffL);*into++ = (unsigned char)((*outof >> 24) & 0xffL);*into++ = (unsigned char)((*outof >> 16) & 0xffL);*into++ = (unsigned char)((*outof >> 8) & 0xffL);*into = (unsigned char)( *outof & 0xffL);return;}void desfunc(register unsigned long *block,register unsigned long *keys) {register unsigned long fval, work, right, leftt;register int round;leftt = block[0];right = block[1];work = ((leftt >> 4) ^ right) & 0x0f0f0f0fL;right ^= work;leftt ^= (work << 4);work = ((leftt >> 16) ^ right) & 0x0000ffffL;right ^= work;leftt ^= (work << 16);work = ((right >> 2) ^ leftt) & 0x33333333L;leftt ^= work;right ^= (work << 2);work = ((right >> 8) ^ leftt) & 0x00ff00ffL;leftt ^= work;right ^= (work << 8);right = ((right << 1) | ((right >>31) & 1L)) & 0xffffffffL;work = (leftt ^ right) & 0xaaaaaaaaL;leftt ^= work;right ^= work;leftt = ((leftt << 1) | ((leftt >> 31)&1L)) & 0xffffffffL;for (round = 0; round < 8; round++) {work = (right << 28) | (right >> 4);work ^= *keys++;fval = SP7[ work & 0x3fL];fval |= SP5[(work >> 8) & 0x3fL];fval |= SP3[(work >> 16) & 0x3fL];fval |= SP1[(work >> 24) & 0x3fL];work = right ^ *keys++;fval |= SP8[ work & 0x3fL];fval |= SP6[(work >> 8) & 0x3fL];fval |= SP4[(work >> 16) & 0x3fL];fval |= SP2[(work >> 24) & 0x3fL];leftt ^= fval;work = (leftt << 28) | (leftt >> 4);work ^= *keys++;fval = SP7[ work & 0x3fL];fval |= SP5[(work >> 8) & 0x3fL];fval |= SP3[(work >> 16) & 0x3fL];fval |= SP1[(work >> 24) & 0x3fL];work = leftt ^ *keys++;fval |= SP8[ work & 0x3fL];fval |= SP6[(work >> 8) & 0x3fL];fval |= SP4[(work >> 16) & 0x3fL];fval |= SP2[(work >> 24) & 0x3fL];right ^= fval;}right = (right << 31) | (right >> 1);work = (leftt ^ right) & 0xaaaaaaaaL;leftt ^= work;right ^= work;leftt = (leftt << 31) | (leftt >> 1);work = ((leftt >> 8) ^ right) & 0x00ff00ffL;right ^= work;leftt ^= (work << 8);work = ((leftt >> 2) ^ right) & 0x33333333L;right ^= work;leftt ^= (work << 2);work = ((right >> 16) ^ leftt) & 0x0000ffffL;leftt ^= work;right ^= (work << 16);work = ((right >> 4) ^ leftt) & 0x0f0f0f0fL;leftt ^= work;right ^= (work << 4);*block++ = right;*block = leftt;return;}/*****************************************************************OPENCOMM_DesExpandEncKey : Expand Des Enc Key 扩展des加密密钥Return value:0 : Successother : failedParameters:pbDesKey : 扩展前的DES密钥(8字节) inputulDesKeyLen : 扩展前的DES密钥长度 inputpbDesEncKey : 扩展后的DES加密密钥(128字节) output*ulDesEncKeyLen : 扩展后的DES加密密钥长度 output*****************************************************************/unsigned long OPENCOMM_DesExpandEncKey(unsigned char *pbDesKey,unsigned long ulDesKeyLen,unsigned char *pbDesEncKey,unsigned long *ulDesEncKeyLen){unsigned long kn[32], dough[32];if (ulDesKeyLen != 8)return 0xEE20;deskey(pbDesKey, EN0, kn);cookey(kn, dough);*ulDesEncKeyLen = DES_KEYBYTES; //32 long = 128 bytesmemcpy(pbDesEncKey, dough, *ulDesEncKeyLen);return 0;}/*****************************************************************OPENCOMM_DesExpandDecKey : Expand Des Dec Key 扩展des解密密钥Return value:0 : Successother : failedParameters:pbDesKey : 扩展前的DES密钥(8字节) inputulDesKeyLen : 扩展前的DES密钥长度 inputpbDesDecKey : 扩展后的DES解密密钥(128字节) output*ulDesDecKeyLen : 扩展后的DES解密密钥长度 output*****************************************************************/unsigned long OPENCOMM_DesExpandDecKey(unsigned char *pbDesKey,unsigned long ulDesKeyLen,unsigned char *pbDesDecKey,unsigned long *ulDesDecKeyLen){unsigned long kn[32], dough[32];if (ulDesKeyLen != 8)return 0xEE20;deskey(pbDesKey, DE1, kn);cookey(kn, dough);*ulDesDecKeyLen = DES_KEYBYTES; //32 long = 128 bytesmemcpy(pbDesDecKey, dough, *ulDesDecKeyLen);return 0;}/****************************************************************OPENCOMM_DesEncRaw : Des算法加密⼩整块明⽂8字节Return value:0 : Successother : failedParameters:pbDesEncKey : DES加密密钥 inputulDesEncKeyLen : DES加密密钥长度 inputpbInData : 待加密的明⽂ inputulInDataLen : 待加密的明⽂长度 inputpbOutData : 加密后的密⽂ output*ulOutDataLen : 加密后的密⽂长度 output*****************************************************************/unsigned long OPENCOMM_DesEncRaw(unsigned char *pbDesEncKey,unsigned long ulDesEncKeyLen,unsigned char *pbInData,unsigned long ulInDataLen,unsigned char *pbOutData,unsigned long *ulOutDataLen){unsigned long work[2], ek[DES_KEYLONGS];unsigned char cp[DES_BLOCKLEN];if (ulInDataLen != DES_BLOCKLEN)return 0xEE20;if (ulDesEncKeyLen != DES_KEYBYTES)return 0xEE20;memcpy(cp, pbInData, DES_BLOCKLEN);scrunch(cp,work); // 8 bytes -> 2 longmemcpy(ek, pbDesEncKey, ulDesEncKeyLen);desfunc(work,ek);unscrun(work,cp); // 2 long -> 8 bytesmemcpy(pbOutData, cp, DES_BLOCKLEN);*ulOutDataLen = DES_BLOCKLEN;return 0;}/***************************************************************** OPENCOMM_DesDecRaw : Des算法解密⼩整块密⽂8字节Return value:0 : Successother : failedParameters:pbDesDecKey : DES解密密钥 input ulDesDecKeyLen : DES解密密钥长度 inputpbInData : 待解密的密⽂ inputulInDataLen : 待解密的密⽂长度 inputpbOutData : 解密后的明⽂ output*ulOutDataLen : 解密后的明⽂长度 output*****************************************************************/ unsigned long OPENCOMM_DesDecRaw(unsigned char *pbDesDecKey,unsigned long ulDesDecKeyLen,unsigned char *pbInData,unsigned long ulInDataLen,unsigned char *pbOutData,unsigned long *ulOutDataLen){unsigned long work[2], dk[DES_KEYLONGS];unsigned char cp[DES_BLOCKLEN];if (ulInDataLen != DES_BLOCKLEN)return 0xEE20;if (ulDesDecKeyLen != DES_KEYBYTES)return 0xEE20;memcpy(cp, pbInData, DES_BLOCKLEN);scrunch(cp,work); // 8 bytes -> 2 longmemcpy(dk, pbDesDecKey, ulDesDecKeyLen);desfunc(work,dk);unscrun(work,cp); // 2 long -> 8 bytesmemcpy(pbOutData, cp, DES_BLOCKLEN);// des_enc(pbDesEncKey, pbInData, pbOutData);*ulOutDataLen = DES_BLOCKLEN;return 0;}/********************* DES *********************/int myic_DESEncrypt(unsigned char *pDesKey,int nDesKeyLen,unsigned char *pInData,int nInDataLen,unsigned char *pOutData,int *pOutDataLen){unsigned char DesKeyBuf[32];unsigned char DesEncKeyBuf[128];int EncKeyLen, KeyLen = 0;int retval = 0, loops, i;if(nInDataLen%8 != 0)return 0xEE20;if(nDesKeyLen != 8)return 0xEE20;KeyLen = nDesKeyLen;memcpy(DesKeyBuf, pDesKey, nDesKeyLen);retval = OPENCOMM_DesExpandEncKey(DesKeyBuf, KeyLen, DesEncKeyBuf, (unsigned long *)&EncKeyLen);if(retval != 0)return retval;loops = nInDataLen/8;for(i = 0; i < loops; i++){retval = OPENCOMM_DesEncRaw(DesEncKeyBuf, EncKeyLen, pInData + i*8, 8, pOutData + i*8, (unsigned long *)pOutDataLen);if(retval != 0)return retval;}*pOutDataLen = nInDataLen;return retval;}int myic_DESDecrypt(unsigned char *pDesKey,int nDesKeyLen,unsigned char *pInData,int nInDataLen,unsigned char *pOutData,int *pOutDataLen){unsigned char DesKeyBuf[32];unsigned char DesDecKeyBuf[128];int DecKeyLen, KeyLen = 0;int retval = 0, loops, i;if(nInDataLen%8 != 0)return 0xEE20;if(nDesKeyLen != 8)return 0xEE20;KeyLen = nDesKeyLen;memcpy(DesKeyBuf, pDesKey, nDesKeyLen);retval = OPENCOMM_DesExpandDecKey(DesKeyBuf, KeyLen, DesDecKeyBuf, (unsigned long *)&DecKeyLen);if(retval != 0)return retval;loops = nInDataLen/8;for(i = 0; i < loops; i++){retval = OPENCOMM_DesDecRaw(DesDecKeyBuf, DecKeyLen, pInData + i*8,8, pOutData + i*8, (unsigned long *)pOutDataLen);if(retval != 0)return retval;}*pOutDataLen = nInDataLen;return retval;}//对称明⽂数据打padingvoid CW_dataPadAdd(int tag, unsigned char *date, unsigned int dateLen,unsigned char **padDate, unsigned int *padDateLen){int i, padLen;unsigned char *pTmp = NULL;pTmp = (unsigned char *)malloc(dateLen+24);if (pTmp == NULL){*padDate = NULL;return ;}memset(pTmp, 0, dateLen+24);memcpy(pTmp, date, dateLen);if (tag == 0){padLen = 8 - dateLen % 8;for (i=0; i<padLen; i++){pTmp[dateLen+i] = (char)padLen;}*padDateLen = dateLen + padLen;}else{padLen = 16 - dateLen % 16;for (i=0; i<padLen; i++){pTmp[dateLen+i] = (char)padLen;}}*padDateLen = dateLen + padLen;*padDate = pTmp;}#define USER_PASSWORD_KEY "abcd1234"//数据加密int DesEnc(unsigned char *pInData,int nInDataLen,unsigned char *pOutData,int *pOutDataLen){int rv;unsigned char *padDate = NULL;unsigned int padDateLen = 0;CW_dataPadAdd(0, pInData, (unsigned int )nInDataLen, &padDate, &padDateLen);rv = myic_DESEncrypt((unsigned char *)USER_PASSWORD_KEY, strlen(USER_PASSWORD_KEY), padDate, (int)padDateLen, pOutData, pOutDataLen);if (rv != 0){if (padDate != NULL){free(padDate);}return rv;}if (padDate != NULL){free(padDate);}return 0;}//数据加密int DesEnc_raw(unsigned char *pInData,int nInDataLen,unsigned char *pOutData,int *pOutDataLen){int rv;unsigned char *padDate = NULL;unsigned int padDateLen = 0;rv = myic_DESEncrypt((unsigned char *)USER_PASSWORD_KEY, strlen(USER_PASSWORD_KEY), pInData, (int)nInDataLen, pOutData, pOutDataLen);if (rv != 0){return rv;}return 0;}//解密分配内存错误#define ERR_MALLOC 20//密码长度不是8的整数倍, 不合法#define ERR_FILECONT 20//⽤户使⽤函数des解密int DesDec(unsigned char *pInData,int nInDataLen,unsigned char *pOutData,int *pOutDataLen){int rv;char padChar;unsigned char *tmpPlain = NULL;tmpPlain = (unsigned char *)malloc(nInDataLen+24);if (tmpPlain == NULL){return ERR_MALLOC;}memset(tmpPlain, 0, nInDataLen+24);//解密rv = myic_DESDecrypt((unsigned char *)USER_PASSWORD_KEY, strlen(USER_PASSWORD_KEY), pInData, nInDataLen, tmpPlain, pOutDataLen);if (rv != 0){if (tmpPlain != NULL) free(tmpPlain);return rv;}//去padingpadChar = tmpPlain[*pOutDataLen - 1];if ( (int)padChar<=0 || (int)padChar>8) //异常处理{if (tmpPlain) free(tmpPlain);return ERR_FILECONT;}*pOutDataLen = *pOutDataLen - (int)padChar;//memset(tmpPlain + *pOutDataLen, 0, (int)padChar);memcpy(pOutData, tmpPlain, *pOutDataLen);if (tmpPlain) free(tmpPlain);return 0;}//⽤户使⽤函数des解密int DesDec_raw(unsigned char *pInData,int nInDataLen,unsigned char *pOutData,int *pOutDataLen){int rv;//char padChar;//unsigned char *tmpPlain = NULL;/*tmpPlain = (unsigned char *)malloc(nInDataLen+24);if (tmpPlain == NULL){return ERR_MALLOC;}memset(tmpPlain, 0, nInDataLen+24);*///解密rv = myic_DESDecrypt((unsigned char *)USER_PASSWORD_KEY, strlen(USER_PASSWORD_KEY), pInData, nInDataLen, pOutData, pOutDataLen);if (rv != 0){//if (tmpPlain != NULL) free(tmpPlain);return rv;}/*//去padingpadChar = tmpPlain[*pOutDataLen - 1];if ( (int)padChar<=0 || (int)padChar>8) //异常处理{if (tmpPlain) free(tmpPlain);return ERR_FILECONT;}*pOutDataLen = *pOutDataLen - (int)padChar;//memset(tmpPlain + *pOutDataLen, 0, (int)padChar);memcpy(pOutData, tmpPlain, *pOutDataLen);if (tmpPlain) free(tmpPlain);*/return 0;}。
DES加密算法与解密(带流程图)
DES加密算法与解密(带流程图)一、DES加密及解密算法程序源代码:#include <iostream>using namespace std;const static char IP_Table[] = { //IP_Table置换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};const static char Final_Table[] = { //最终置换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};const static char S_Box[8][64] = {//s_box/* S1 */{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13},/* S2 */{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10,14, 5, 2, 8, 4,3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14},/* S5 */{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3},/* S6 */{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13},/* S7 */{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12},/* S8 */{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}const static char Rar_Table[] = { //压缩置换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};const static char Exp_Table[] = { //扩展置换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, 1const static char P_Table[]={ //P置换16, 7, 20, 21,29, 12, 28, 17,1, 15, 23, 26,5, 18, 31, 10,2, 8, 24, 14,32, 27, 3, 9,19, 13, 30, 6,22, 11, 4, 25};const static char KeyRar_Table[]={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};//设置全局变量,16轮密钥bool key[16][48]={{0}};void ByteToBit(bool *Out,char *In,int bits) //字节到位转换函数{int i;for(i=0;i<bits;i++)Out[i]=(In[i/8]>>(i%8))&1;}void BitToByte(char *Out,bool *In,int bits)//位到字节转换函数{int i;for(i=0;i<bits/8;i++)Out[i]=0;for(i=0;i<bits;i++)Out[i/8]|=In[i]<<(i%8);}void Xor(bool *InA,const bool *InB,int length) //按位异或for(int i=0;i<length;i++)InA[i]^=InB[i];}void keyfc(char *In) //密钥生成函数{int i,j=0,mov,k,m;bool* key0 = new bool[56];bool* keyin = new bool[64];bool temp;ByteToBit(keyin,In,64); //字节到位的转换for(i=0;i<56;i++) //密钥压缩为56位key0[i]=keyin[KeyRar_Table[i]-1];for(i=0;i<16;i++) //16轮密钥产生{if(i==0||i==1||i==8||i==15)mov=1;elsemov=2;for(k=0;k<mov;k++) //分左右两块循环左移{for(m=0;m<8;m++){temp=key0[m*7];for(j=m*7;j<m*7+7;j++)key0[j]=key0[j+1];key0[m*7+6]=temp;}temp=key0[0];for(m=0;m<27;m++)key0[m]=key0[m+1];key0[27]=temp;temp=key0[28];for(m=28;m<55;m++)key0[m]=key0[m+1];key0[55]=temp;}for(j=0;j<48;j++) //压缩置换并储存key[i][j]=key0[Rar_Table[j]-1];}delete[] key0;delete[] keyin;}void DES(char Out[8],char In[8],bool Type)//加密核心程序,Type=0时加密,反之解密{bool* MW = new bool[64];bool* tmp = new bool[32];bool* PMW = new bool[64];bool* kzmw = new bool[48];bool* keytem = new bool[48];bool* ss = new bool[32];int hang,lie,i;ByteToBit(PMW,In,64);for(int j=0;j<64;j++){MW[j]=PMW[IP_Table[j]-1]; //初始置换}bool *Li=&MW[0],*Ri=&MW[32];for(i=0;i<48;i++) //右明文扩展置换kzmw[i]=Ri[Exp_Table[i]-1];if(Type==0) //DES加密过程{for(int lun=0;lun<16;lun++){for(i=0;i<32;i++)ss[i]=Ri[i];for(i=0;i<48;i++) //右明文扩展置换kzmw[i]=Ri[Exp_Table[i]-1];for(i=0;i<48;i++)keytem[i]=key[lun][i];Xor(kzmw,keytem,48);/*S盒置换*/for(i=0;i<8;i++)hang=kzmw[i*6]*2+kzmw[i*6+5];lie=kzmw[i*6+1]*8+kzmw[i*6+2]*4+kzmw[i*6+3] *2+kzmw[i*6+4];tmp[i*4+3]=S_Box[i][(hang+1)*16+lie]%2;tmp[i*4+2]=(S_Box[i][(hang+1)*16+lie]/2)%2 ;tmp[i*4+1]=(S_Box[i][(hang+1)*16+lie]/4)%2 ;tmp[i*4]=(S_Box[i][(hang+1)*16+lie]/8)%2;}for(i=0;i<32;i++) //P置换Ri[i]=tmp[P_Table[i]-1];Xor(Ri,Li,32); //异或for(i=0;i<32;i++) //交换左右明文Li[i]=ss[i];}}for(i=0;i<32;i++){tmp[i]=Li[i];Li[i]=Ri[i];Ri[i]=tmp[i];}for(i=0;i<64;i++)PMW[i]=MW[Final_Table[i]-1];BitToByte(Out,PMW,64); //位到字节的转换}else //DES解密过程{for(int lun=15;lun>=0;lun--){for(i=0;i<32;i++)ss[i]=Ri[i];for(i=0;i<48;i++) //右明文扩展置换kzmw[i]=Ri[Exp_Table[i]-1];for(i=0;i<48;i++)keytem[i]=key[lun][i];Xor(kzmw,keytem,48);/*S盒置换*/for(i=0;i<8;i++){hang=kzmw[i*6]*2+kzmw[i*6+5];lie=kzmw[i*6+1]*8+kzmw[i*6+2]*4+kzmw[i*6+3] *2+kzmw[i*6+4];tmp[i*4+3]=S_Box[i][(hang+1)*16+lie]%2;tmp[i*4+2]=(S_Box[i][(hang+1)*16+lie]/2)%2 ;tmp[i*4+1]=(S_Box[i][(hang+1)*16+lie]/4)%2 ;tmp[i*4]=(S_Box[i][(hang+1)*16+lie]/8)%2; }for(i=0;i<32;i++) //P置换Ri[i]=tmp[P_Table[i]-1];Xor(Ri,Li,32); //异或for(i=0;i<32;i++) //交换左右明文{Li[i]=ss[i];}}for(i=0;i<32;i++){tmp[i]=Li[i];Li[i]=Ri[i];Ri[i]=tmp[i];}for(i=0;i<64;i++)PMW[i]=MW[Final_Table[i]-1]; BitToByte(Out,PMW,64); //位到字节的转换}delete[] MW;delete[] tmp;delete[] PMW;delete[] kzmw;delete[] keytem;delete[] ss;}bool RunDes(char *Out, char *In, int datalength, char *Key, bool Type) //加密运行函数,判断输入以及对输入文本8字节分割{if( !( Out && In && Key && (datalength=(datalength+7)&0xfffffff8) ) ) return false;keyfc(Key);for(int i=0,j=datalength%8; i<j; ++i,Out+=8,In+=8)DES(Out, In, Type);return true;}int main(){char* Ki = new char[8];char Enter[]="This is the test of DES!"; char* Print = new char[200];int len = sizeof(Enter);int i_mf;cout << "请输入密钥(8位):" <<"\n"; for(i_mf=0;i_mf<8;i_mf++)cin >> Ki[i_mf];cout << "\n";RunDes(Print,Enter,len,Ki,0);//加密cout << "----加密前----" << "\n";for(i_mf=0;i_mf<len;i_mf++)cout << Enter[i_mf];cout << "\n\n";cout << "----加密后----" << "\n";for(i_mf=0;i_mf<len;i_mf++)cout<<Print[i_mf];cout << "\n\n";//此处进行不同密钥输入测试cout << "请输入密钥(8位):" <<"\n"; for(i_mf=0;i_mf<8;i_mf++)cin >> Ki[i_mf];cout << "\n";RunDes(Enter,Print,len,Ki,1);//解密cout << "----解密后----" << "\n";for(i_mf=0;i_mf<len;i_mf++)cout << Enter[i_mf];cout << endl;delete[] Ki;delete[] Print;return 0;}二、程序编译、运行结果图:三、程序总体框架图:读取待加密文本输入密钥DES 加密显示加密后文本再次输入密钥DES 解密显示解密后文本显示错误解密信息密钥错误密钥正确四、程序实现流程图:Enter = 待加密文本分割Enter ,8字节为一段,不足补加,段数为N 初始化:*Print ,i=0,j=0文本第i 段,转为二进制64位初始置换(IP_Table )文本段分为左右两部分左部分(32位)右部分(32)输入8字节密钥转为二进制64位密钥压缩KeyRar_Table (56位)形成16轮密钥合并形成子密钥(48位)S 置换(S_Box )P 置换(P_Table )左右交换,j++最终置换(Final_Table )J<16扩展置换(Exp_Table )i<N异或异或NoYes存入*Print ,i++DES 加密过程结束,输出Print YesNoDES 解密过程为以上逆过程。
DES加密算法
DES加密算法1950年代末至1970年代初,密码学家发现了许多消息传递系统被成功入侵的案例。
为了应对这种威胁,美国国家安全局(NSA)与IBM公司合作开发了一种新的加密算法,即数据加密标准(Data Encryption Standard,简称DES)。
DES在20世纪70年代末被正式采纳,并成为许多国家及组织使用的标准加密算法,它不仅安全可靠,而且非常高效。
本文将对DES加密算法进行详细介绍。
一、DES加密算法简介DES加密算法是一种对称密钥算法,使用相同的密钥进行加密和解密。
在加密和解密过程中,DES算法将数据分成64位大小的数据块,并进行一系列置换、替换、混淆和反混淆等操作。
DES算法共有16轮运算,每轮运算都与密钥有关。
最终输出的密文与64位的初始密钥相关联,只有使用正确的密钥才能解密并还原原始数据。
二、DES加密算法的原理DES算法的核心是通过一系列的置换、替换和混淆技术对数据进行加密。
以下是DES算法的主要步骤:1. 初始置换(Initial Permutation)DES算法首先将明文进行初始置换,通过一系列规则将64位明文重新排列。
2. 轮函数(Round Function)DES算法共有16个轮次,每轮都包括以下几个步骤:a) 拓展置换(Expansion Permutation)将32位的数据扩展为48位,并进行重新排列。
b) 密钥混淆(Key Mixing)将48位的数据与轮次对应的子密钥进行异或运算。
c) S盒代替(S-box Substitution)将48位的数据分为8个6位的块,并根据S盒进行替换。
S盒是一个具有固定映射关系的查找表,用于增加加密算法的复杂性和安全性。
d) 置换函数(Permutation Function)经过S盒代替后,将得到的数据再进行一次置换。
3. 左右互换在每轮的运算中,DES算法将右半部分数据与左半部分进行互换,以实现加密算法的迭代。
4. 逆初始置换(Inverse Initial Permutation)最后,DES算法对经过16轮运算后的数据进行逆初始置换,得到最终的密文。
DES加密算法.
数据加密标准DES(Data Encryption Standard)算法是由美国IBM公司研制的一种分组密码算法,一种迭代分组密码。
DES是一种使用最为广泛的加密算法,虽然DES出现后又产生了许多常规加密算法,但DES仍是此类算法中最重要的一种。
在正式讨论DES算法之前,为了更好的理解算法的实际工作过程,我们先来看一个简化的DES算法,以此加深对DES算法的理解。
一、简化的DES加密算法简化的DES加密算法是以8bit的明文分组和10bit密钥作为输入,产生8bit 密文分组作为输出。
1、加密流程简化的DES算法基本加密流程如图6.9所示图6.9 简化的DES的加密过程2、加密算法构成:函数、SW置换函简单DES的加密算法包括4个基本函数:初始置换函数IP、fk数、逆置换函数IP-1。
(1)初始置换函数IP初始置换IP是将明文中数据的排列顺序按一定的规则重新排列,而生成新的数据序列的过程。
如图6.10所示:8bit原数据位置 1 2 3 4 5 6 7 8【IP置换】经IP置换后的数据位置 2 6 3 1 4 8 5 7图6.10 简单DES的初始置换例:设8bit数据为11110011 ,则初始置换后的结果为:函数f k函数是多个置换函数和替代函数的组合函数。
f k函数首先将输(2) fk入它的8bit数据进行分组,分成左4位和右4位,然后对右组的4位数据进行E/P扩展置换运算,接着将扩展置换所得的8bit数据与子密钥进行异或运算,再将异或运算所得结果通过S盒输出,再将通过S盒输出的数据进行P4置换,最后将经过P4置换后的数据与输入f函数经分组的左4位数据进行异或运算。
kF(R,SK)函数是f k函数的核心函数,其中SK是子密钥。
F(R,SK)函数的运算方法如下:f k(L,R)=(L⊕F(R,SK),R)L:输入的左边4位分组 R:输入的右边4位分组⊕:逐位异或①扩展/置换是将4bit输入数据经过置换和扩展而产生8bit数据的算法。
DES算法(基于某C语言,加密解密代码)
/* Note:Your choice is C IDE */#include"stdio.h"#include"string.h"#define uchar unsignedchar/*************************************************************************** *******************************明文转换声明局部*******************************///IP1置换表int IP_1[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};//IP2逆置换表int IP_2[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};//E扩展置换表int E_case[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};//S盒压缩int S1[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};int S2[4][16]={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};int S3[4][16]={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};int S4[4][16]={ 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4,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};int S5[4][16]={ 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};int S6[4][16]={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,4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13};int S7[4][16]={ 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};int S8[4][16]={13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11};//P盒置换int Permute[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 ByteToBit(char ch,char bit[8]){uchar x;for(x=0;x<8;x++){*(bit+x)=((ch<<x)&0x80)>>7;}return 0;}//字符串转换成二进制位串int Char8ToBit64(char ch[8],char bit[64]) {uchar x;for(x=0;x<8;x++){ByteToBit(*(ch+x),bit+(x<<3)); }return 0;}//二进制转换成字节int BitToByte(char bit[8],char*ch){uchar x;for(x=0;x<8;x++){*ch|=*(bit+x)<<(7-x);}return 0;}//将二进制串转换成字符串int Bit64ToChar8(char bit[64],char ch[8]){uchar x;memset(ch,0,8); //把ch[8]全部清零。
加密算法之DES算法
加密算法之DES算法DES算法(Data Encryption Standard,数据加密标准)是一种对称加密算法,由IBM公司于1970年代开发,1977年被美国国家标准局(NIST)采纳为联邦信息处理标准(FIPS),并作为加密通信的标准算法使用。
DES算法采用分组密码(Block Cipher)的形式,将明文数据分成64位的数据块进行加密和解密操作。
DES算法的核心是Feistel结构,该结构由两个相同的数据块进行操作,每一轮加密过程包括分组加密、轮密钥生成和异或运算三个步骤。
下面将详细介绍DES算法的加密过程。
1.密钥生成:DES算法使用56位的密钥进行加密,其中有8位用于奇偶校验,因此实际有效密钥长度为48位。
首先,将56位密钥进行置换和分割,得到两个28位的子密钥,分别为左子密钥和右子密钥。
接着,根据子密钥生成算法对左右子密钥进行16轮循环左移操作,每轮循环左移的位数由一个预定义的位移表决定,最终得到16个48位的轮密钥。
2.分组加密:将64位明文数据分成左右两个32位的数据块,分别为左数据块L0和右数据块R0。
接下来,采用16轮的迭代过程,每轮过程包括以下四个步骤:-迭代函数扩展:将32位的右数据块扩展为48位,通过一个预定义的扩展换位表进行操作,得到扩展后的数据块。
-轮密钥混合:将扩展后的数据块和对应的轮密钥进行异或运算,得到48位的中间结果。
-S盒代替:将中间结果进行分组,每个6位作为一个输入,通过一系列预定义的S盒进行替代操作,得到32位的输出。
-P盒置换:对S盒代替的输出进行置换操作,通过一个预定义的置换表得到32位的最终结果。
在每轮迭代过程中,将左右数据块交换位置,即Li=Ri-1,Ri=Li-1⊕F(Ri-1,Ki),其中F表示迭代函数,Ki表示对应的轮密钥。
3.逆置换:经过16轮迭代后,得到的最终结果为L16和R16,将其交换位置,即L16为右数据块,R16为左数据块。
DES加密算法代码
DES加密算法代码java实现DES加密1.准备算法所需要的密钥在Java中,DES加密算法需要一个8字节长的密钥,这里使用原始的8字节长的密钥来实现DES加密算法,同时,还有一种是“密钥扩展”,可以将8字节长的密钥扩展为16字节长,只需要多添加8个字节,后面8个字节可以跟前面8字节保持一致即可,即扩展后的密钥和原始密钥共享后八个字节即可。
byte [] keyBytes = {0x11, 0x22, 0x4F, 0x58, (byte) 0x88,0x10, 0x40, 0x38,0x28, 0x25, 0x79, 0x51, (byte) 0xCB, (byte) 0xDD, 0x55, 0x66, 0x77, 0x29, 0x74, (byte) 0x98, 0x30, 0x40, 0x36, (byte)0xE2};下面介绍如何用Java来实现原始的8字节长的密钥:// 生成keyKeyGenerator keyGenerator = KeyGenerator.getInstance("DES");keyGenerator.init(new SecureRandom(keyBytes));SecretKey key = keyGenerator.generateKey(;2. 设置加密模式(Cipher Block Chaining Mode,简称CBC模式)在Java中,DES加密算法可以支持三种不同的加密模式:ECB,CBC,CFB。
其中ECB模式为最原始的模式,它不需要任何附加的参数,而CBC模式需要一个8字节的初始向量(Initial Vector,IV)参数,CFB模式需要一个1字节或8字节的变量参数,它们用来增加加密的强度。
这里,我们使用CBC模式,它是最常用的DES加密模式,下面是设置CBC模式所需要的参数:// 创建Cipher对象,指定其支持的DES算法Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");// 用密匙初始化Cipher对象IvParameterSpec param = new IvParameterSpec(iv);cipher.init(Cipher.ENCRYPT_MODE, key,param);3.加密。
des加密算法例题详解
des加密算法例题详解DES加密算法例题详解什么是DES加密算法?DES(Data Encryption Standard)是一种对称加密算法,由美国联邦政府于1977年确定为非机密政府通信的标准。
DES是一种块密码,以64位为块长度,使用56位的密钥对数据进行加密和解密。
DES加密算法的流程1.首先,将输入数据分组为64位的块。
2.然后,根据规定的密钥生成16个48位的子密钥。
3.接下来,使用生成的子密钥对数据进行16轮的加密和解密操作。
4.最后,将加密或解密后的数据进行合并,得到最终的结果。
DES加密算法的例题下面通过一个例题来详细解释DES加密算法的过程。
假设输入数据为:“Hello World!”,密钥为:“SecretKey”。
1. 数据分组将输入数据“Hello World!” 分组为 64 位块:•第一个块:“Hello Wo”)•第二个块:“rld!”)2. 生成子密钥根据密钥“SecretKey”,使用DES算法生成 16 个 48 位的子密钥。
3. 加密操作对每个数据块进行 16 轮的加密操作。
•第一轮加密:–输入数据块:““(”Hello Wo”)–扩展置换(E-Box):–密钥:“SubKey1”–异或运算:–S 盒代替:–P 盒置换:–交换左右:–加密结果:“11”•第二轮加密:–输入数据块:““(”rld!“)–扩展置换(E-Box):–密钥:“SubKey2”–异或运算:–S 盒代替:–P 盒置换:–交换左右:–加密结果:“10”…4. 合并结果将加密后的数据块进行合并,得到最终的加密结果。
•加密结果:“”总结DES加密算法是一种经典的对称加密算法,通过对输入数据进行分组、生成子密钥、多轮加密操作和结果合并,实现数据的加密和解密。
它在信息安全领域有着广泛的应用,但由于密钥长度较短,已被认为不够安全。
DES加密算法的安全性问题尽管DES加密算法在过去是被广泛采用的标准算法,但是它的密钥长度较短,只有56位,容易受到穷举攻击。
DES算法工作原理甄选文档
DES算法工作原理3 DES算法的原理研究3.1 DES算法的产生与发展DES是在1970年代中期由美国IBM公司发展出来的,且被美国国家标准局(NBS)公布为数据加密标准的一种分组加密法。
1972年,NBS制定了一个保护计算机和通信开发计划,准备开发一个标准的密码算法,来规范密码技术应用的混乱局面。
1973年5月15日,NBS 公开征集保密传输系统中计算机数据密码算法,由于此前公众对密码知识的缺乏,提交的方案均不理想。
1974年8月27日,NBS再次发表征集公告,IBM公司提交了个良好的候选算法。
该算法是LUCIFFER 密码算法的改进,是由Host Feistel 1971年设计的。
1975年3月17日,NBS在《联邦记事》上公布了这一算法的细节。
1981年,美国国家标准研究所批准DES作为私营部门的数据加密标准[3]。
讼貺貶缃鏷爷脹绺覺賊绳赉闱飕镗瓯啬侦韃镙顶陘尝撷渖聪庆阎杀東捣屡贝桡褛彦輻渊皲魎钺鉉肃鮪駘縈綆嘵滌夠。
3.2 DES算法的基本原理3.2.1 DES算法的总结构DES是一个分组加密算法,它以64位为分组对数据加密,所用的加解密密钥也是64位大小,其中8个位用来做奇偶校验,所以实际用来加解密的密钥为56位。
DES算法加密与解密所用的算法除了子密钥的顺序不同之外,其他的部分则是完全相同的。
其加密/解密结构如图3.1所示。
在结构图最上方的64位输入可以是明文也可以是密文,视加密或解密而定,加密与解密的不同之处在于最右面密钥的顺序不同,加密的子密钥顺序为K1,K2,……,K16,而解密的子密钥顺序为K16,K15,……,K1。
在进行加密或解密时,首先对输入的内容进行初始置换,然后分为L0和R0两部分,R0和子密钥K1进行f函数运算与L0异或后作为下一轮的R1,而R0作为下一轮的L1,如此运作16轮,再进行初始置换的逆置换,得到64位输出[5]。
爍缎攤绣秽鲳霧犹撳纱锥鲵鳟鳓鮭鱔殼镑勝万轭殡釋虽赉痫厂哟鹳鶻賞枥湊缳錫坚谛廠驊頑錢麸澇谩嶸頓诊缥弑風。
DES算法结构范文
DES算法结构范文1. 初始置换(Initial Permutation,IP)初始置换是将64位明文按照指定规则进行重排列,以生成一个新的64位序列作为Feistel网络的输入。
初始置换通过混淆数据的位置来增加密码的随机性,从而增强加密的安全性。
2. Feistel网络Feistel网络是DES算法的核心部分,由16个相同的轮函数组成。
每一轮函数都接受32位输入数据和48位子密钥作为输入,并输出一个32位的中间结果。
轮函数包含四个主要步骤:扩展置换、异或运算、S盒替代和置换函数。
- 扩展置换(Expansion Permutation,E)扩展置换将32位输入数据按照指定规则扩展为48位,增加数据的长度。
通过扩展置换,可以提取更多的信息用于后续的异或运算。
-异或运算将48位的扩展数据与48位子密钥进行异或运算,得到一个48位的中间结果。
- S盒替代(S-box Substitution)S盒替代是DES算法的核心操作之一、它将48位中间结果分割为8个6位的分组,并将每个6位分组替代为4位的输出。
S盒是由8个不同的4×16的置换表组成,每个表都有6位的输入和4位的输出。
S盒替代能够通过将6位输入映射到4位输出来进一步混淆数据。
- 置换函数(Permutation Function,P)在S盒替代之后,将32位的数据经过一个固定的置换函数,以混淆数据的顺序,再次增加密码的随机性。
3. 末置换(Final Permutation,FP)末置换是将Feistel网络输出的32位数据按照指定规则进行重排列,以生成最终的64位密文。
末置换与初始置换相似,旨在通过混淆数据的位置来增强加密的安全性。
在DES算法中,密钥的长度为56位,其中8位用于奇偶校验检查。
为了提高密钥的安全性,DES算法采用了密钥调度算法将56位的密钥扩展为16个48位的子密钥,每个子密钥只在Feistel网络中的一轮使用。
虽然DES算法曾经是非常流行的加密算法,但由于其密钥长度较短,易受到暴力破解和密码分析等攻击,因此在现代密码学中已被更安全的加密算法(如AES)所取代。
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的工作原理为:将明文分割成许多64位大小的块,每个块用64位密钥进行加密,实际上,密钥由56位数据位和8 位奇偶校验位组成,因此只有256个可能的密码而不是264个。
每块先用初始置换方法进行加密,再连续进行16次复杂的替换,最后再对其施用初始置换的逆。
第i步的替换并不是直接利用原始的密钥K,而是由K与i计算出的密钥Ki。
DES具有这样的特性,其解密算法与加密算法相同,除了密钥Ki的施加顺序相反外。
为DES并不是真的很安全。
事实上,即使不采用智能的方法,随着快速、高度并行的处理器的出现,强制破解DES也是可能的。
"公开密钥"加密方法使得DES以及类似的传统加密技术过时了。
公开密钥加密方法中,加密算法和加密密钥都是公开的,任何人都可将明文转换成密文。
但是相应的解密密钥是保密的(公开密钥方法包括两个密钥,分别用于加密和解密),而且无法从加密密钥推导出,因此,即使是加密者若未被授权也无法执行相应的解密。
公开密钥加密思想最初是由Diffie和Hellman提出的,最著名的是Rivest、Shamir以及Adleman提出的,现在通常称为RSA(以三个发明者的首位字母命名)的方法该方法基于下面的两个事实: 1) 已有确定一个数是不是质数的快速算法; 2) 尚未找到确定一个合数的质因子的快速算法。
RSA方法的工作原理如下: 1) 任意选取两个不同的大质数p和q,计算乘积r=p*q; 2) 任意选取一个大整数e,e与(p-1)*(q-1)互质,整数e用做加密密钥。
注意:e的选取是很容易的,例如,所有大于p和q的质数都可用。
3) 确定解密密钥d:d *e = 1 modulo(p - 1)*(q - 1) 根据e、p和q可以容易地计算出d。
4) 公开整数r和e,但是不公开d; 5) 将明文P (假设P是一个小于r的整数)加密为密文C,计算方法为: C = Pe modulo r 6) 将密文C解密为明文P,计算方法为: P = Cd modulo r 然而只根据r和e(不是p和q)要计算出d是不可能的。
DES算法(经典)
2.2.2 IP-1 是 IP 的逆置换
由于第一位经过初始置换后,处于第 40 位,通过逆置换,又将第 40 位换回到第 1 位,起逆 置换规则如下表所示:
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
2.2.3 DES 算法的迭代过程
DES 算法的迭代过程图(略) 图中 Li-1和 Ri-1 分别是第 i-1 次迭代结果的左右两部分,各 32 比特。即 Li=Ri-1, Ri=Li-1 ,k ) f (Ri-1 i L0,R0 是初始输入经 IP 置换的结果 ki 是由 64 比特的密钥产生的子密钥,ki 是 48 比特
des共享加密算法
加密算法------DES加密算法详解一、加密算法的分类1.对称加解密算法a.通信双方同时掌握一个密钥,加密解密都是由一个密钥完成的(即加密密钥等于解密密钥,加解密密钥可以相互推倒出来)。
b.双方通信前共同拟定一个密钥,不对第三方公开。
c.不具有个体原子性,一个密钥被共享,泄漏几率增大2.公私钥加解密算法a.通信双方掌握不同的密钥,不同方向的加解密由不同的密钥完成。
二、对称加密算法的代表----DES加密算法原理:该算法是一个利用56+8奇偶校验位(第8,16,24,32,40,48,56,64)=64位的密钥对以64位为单位的块数据进行加解密。
具体过程:有明文M(64位)= 0123456789ABCDEF即M(64位)= 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111L(32位)= 0000 0001 0010 0011 0100 0101 0110 0111R(32位)= 1000 1001 1010 1011 1100 1101 1110 1111有密钥64位:133457799BBCDFF1即K(64位)= 0001001100110100010101110111100110011011 10111100 11011111 11110001注:其中红色为奇偶校验位,即实际密钥为56位第一步:按照下表中的规则对各个位进行交换,生成16个子钥(48位)交换规则表(8*7):57 49 41 33 25 17 91 58 50 42 34 26 1810 2 59 51 43 35 2719 11 3 60 52 44 3663 55 47 39 31 23 157 62 54 46 38 30 2214 6 61 53 45 37 2921 13 5 28 20 12 4交换方法:第一行第一列的数为57,那么就将K中第一位上的数换成K中第57位上的数(将0换为了57位上的1),依次类推。
DES加密算法
DES加密算法这个类实现了DES算法,如果你的数据块data的大小sizeof(data)是8的倍数的话,可以使用函数DES::encrypt(key,data,sizeof(data)/8)来进行加密,用DES::decrypt(key,data,sizeof(data)/8)来进行解密。
如果数据块的大小是随意的,那么可以使用函数DES::yencrypt()和DES::ydecrypt()来进行加解密。
这个模块的面向对象的设计不是很好,与其说是一个类,不如说是一个模块的函数集合。
#ifndef __DES_H#define __DES_Hclass DES {public:// Encrypt/decrypt the data in "data", according to the "key".// Caller is responsible for confirming the buffer size of "data"// points to is 8*"blocks" bytes.// The data encrypted/decrypted is stored in data.// The return code is 1:success, other:failed.int encrypt ( char key[8], char* data, int blocks = 1 );int decrypt ( char key[8], char* data, int blocks = 1 );// Encrypt/decrypt any size data,according to a special method.// Before calling yencrypt, copy data to a new buffer with size// calculated by extend.int yencrypt ( char key[8], char* data, int size );int ydecrypt ( char key[8], char* in, int blocks, int* size = 0 );int extend ( int size ) { return (size/8+1)*8; };private:void des(unsigned char* in, unsigned char* out, int blocks);void des_block(unsigned char* in, unsigned char* out);private:unsigned long KnL[32];enum Mode { ENCRYPT, DECRYPT };void deskey(unsigned char key[8], Mode md);void usekey(unsigned long *);void cookey(unsigned long *);private:void scrunch(unsigned char *, unsigned long *);void unscrun(unsigned long *, unsigned char *);void desfunc(unsigned long *, unsigned long *);private:static unsigned char Df_Key[24];static unsigned short bytebit[8];static unsigned long bigbyte[24];static unsigned char pc1[56];static unsigned char totrot[16];static unsigned char pc2[48];static unsigned long SP1[64];static unsigned long SP2[64];static unsigned long SP3[64];static unsigned long SP4[64];static unsigned long SP5[64];static unsigned long SP6[64];static unsigned long SP7[64];static unsigned long SP8[64];};#endif#include <mem.h>#include "des.h"int DES::encrypt ( char key[8], char* data, int blocks ){if ((!data)||(blocks<1))return 0;deskey ( key, ENCRYPT );des ( data, data, blocks);return 1;};int DES::decrypt ( char key[8], char* data, int blocks ){if ((!data)||(blocks<1))return 0;deskey ( key, DECRYPT );des ( data, data, blocks);return 1;};int DES::yencrypt ( char key[8], char* data, int size ){if ((!data)||(size<1))return 0;// The last char of data is bitwise complemented and filled the rest // buffer.If size is 16, it will extend to 24,and 17 still 24.char lastChar = *(data+size-1);int blocks = size/8+1;memset (data+size, ~lastChar, blocks*8-size);deskey ( key, ENCRYPT );return encrypt ( data, data, blocks);};int DES::ydecrypt ( char key[8], char* data, int blocks, int* size ) {if ( (!data) || (blocks<1) )return 0;deskey ( key, DECRYPT );if ( !decrypt ( data, data, blocks) )return 0;if ( size != 0 ){int pos = blocks*8-1;char endChar = data[pos];while ((pos>0)&&(data[pos]==endChar))pos--;if ( data[pos] != ~endChar )return 0;*size = pos+1;}return 1;};// -----------------------------------------------------------------------// des// Encrpts/Decrypts(according to the key currently loaded int the // internal key register) SOME blocks of eight bytes at address 'in' // into the block at address 'out'. They can be the same.//// "in"// "out"// "block" Number of blocks.// -----------------------------------------------------------------------void DES::des ( unsigned char* in, unsigned char* out, int blocks ) {for (int i = 0; i < blocks; i++,in+=8,out+=8)des_block(in,out);};// -----------------------------------------------------------------------// des_block// Encrpts/Decrypts(according to the key currently loaded int the // internal key register) one block of eight bytes at address 'in'// into the block at address 'out'. They can be the same.//// "in"// "out"// -----------------------------------------------------------------------void DES::des_block(unsigned char *in, unsigned char *out){unsigned long work[2];scrunch(in, work);desfunc(work, KnL);unscrun(work, out);}// ----------------------------------------------------------------------// deskey// Sets the internal key register (KnR) according to the hexadecimal// key contained in the 8 bytes of hexkey, according to the DES,// for encryption or decrytion according to MODE//// "key" is the 64 bits key.// "md" means encryption or decryption.// ----------------------------------------------------------------------void DES::deskey(unsigned char key[8], Mode md) /* Thanks to James Gillogly & Phil Karn! */{register int i, j, l, m, n;unsigned char pc1m[56], pcr[56];unsigned long kn[32];for (j = 0; j < 56; j++) {l = pc1[j];m = l & 07;pc1m[j] = (key[l >> 3] & bytebit[m]) ? 1:0;}for (i = 0; i < 16; i++) {if (md == DECRYPT) m = (15 - i) << 1;else m = i << 1;n = m + 1;kn[m] = kn[n] = 0L;for (j = 0; j < 28; j++) {l = j + totrot[i];if (l < 28) pcr[j] = pc1m[l];else pcr[j] = pc1m[l - 28];}for (j = 28; j < 56; j++) {l = j + totrot[i];if (l < 56) pcr[j] = pc1m[l];else pcr[j] = pc1m[l - 28];}for (j = 0; j < 24; j++) {if (pcr[ pc2[j] ]) kn[m] |= bigbyte[j];if (pcr[ pc2[j+24] ]) kn[n] |= bigbyte[j];}}cookey(kn);return;}// ----------------------------------------------------------------------// cookey// Only called by deskey.// -----------------------------------------------------------------------void DES::cookey(register unsigned long *raw1){register unsigned long *cook, *raw0;unsigned long dough[32];register int i;cook = dough;for (i = 0; i < 16; i++, raw1++) {raw0 = raw1++;*cook = (*raw0 & 0x00fc0000L) << 6;*cook |= (*raw0 & 0x00000fc0L) << 10;*cook |= (*raw1 & 0x00fc0000L) >> 10;*cook++ |= (*raw1 & 0x00000fc0L) >> 6;*cook = (*raw0 & 0x0003f000L) << 12;*cook |= (*raw0 & 0x0000003fL) << 16;*cook |= (*raw1 & 0x0003f000L) >> 4;*cook++ |= (*raw1 & 0x0000003fL);}usekey(dough);return;}// ----------------------------------------------------------------------// usekey// Only called by cookey.// Loads the interal key register with the data in cookedkey.// -----------------------------------------------------------------------void DES::usekey(register unsigned long *from){register unsigned long *to, *endp;to = KnL, endp = &KnL[32];while (to < endp) *to++ = *from++;return;}void DES::scrunch(register unsigned char *outof, register unsigned long *int o ){*into = (*outof++ & 0xffL) << 24;*into |= (*outof++ & 0xffL) << 16;*into |= (*outof++ & 0xffL) << 8;*into++ |= (*outof++ & 0xffL);*into = (*outof++ & 0xffL) << 24;*into |= (*outof++ & 0xffL) << 16;*into |= (*outof++ & 0xffL) << 8;*into |= (*outof & 0xffL);return;}void DES::unscrun(register unsigned long *outof, register unsigned char *int o){*into++ = (*outof >> 24) & 0xffL;*into++ = (*outof >> 16) & 0xffL;*into++ = (*outof >> 8) & 0xffL;*into++ = *outof++ & 0xffL;*into++ = (*outof >> 24) & 0xffL;*into++ = (*outof >> 16) & 0xffL;*into++ = (*outof >> 8) & 0xffL;*into = *outof & 0xffL;return;}void DES::desfunc(register unsigned long *block,register unsigned long *keys ){register unsigned long fval, work, right, leftt;register int round;leftt = block[0];right = block[1];work = ((leftt >> 4) ^ right) & 0x0f0f0f0fL;right ^= work;leftt ^= (work << 4);work = ((leftt >> 16) ^ right) & 0x0000ffffL;right ^= work;leftt ^= (work << 16);work = ((right >> 2) ^ leftt) & 0x33333333L;leftt ^= work;right ^= (work << 2);work = ((right >> 8) ^ leftt) & 0x00ff00ffL;leftt ^= work;right ^= (work << 8);right = ((right << 1) | ((right >> 31) & 1L)) & 0xffffffffL;work = (leftt ^ right) & 0xaaaaaaaaL;leftt ^= work;right ^= work;leftt = ((leftt << 1) | ((leftt >> 31) & 1L)) & 0xffffffffL; for (round = 0; round < 8; round++) {work = (right << 28) | (right >> 4);work ^= *keys++;fval = SP7[work & 0x3fL];fval |= SP5[(work >> 8) & 0x3fL];fval |= SP3[(work >> 16) & 0x3fL];fval |= SP1[(work >> 24) & 0x3fL];work = right ^ *keys++;fval |= SP8[work & 0x3fL];fval |= SP6[(work >> 8) & 0x3fL];fval |= SP4[(work >> 16) & 0x3fL];fval |= SP2[(work >> 24) & 0x3fL];leftt ^= fval;work = (leftt << 28) | (leftt >> 4);work ^= *keys++;fval = SP7[work & 0x3fL];fval |= SP5[(work >> 8) & 0x3fL];fval |= SP3[(work >> 16) & 0x3fL];fval |= SP1[(work >> 24) & 0x3fL];work = leftt ^ *keys++;fval |= SP8[work & 0x3fL];fval |= SP6[(work >> 8) & 0x3fL];fval |= SP4[(work >> 16) & 0x3fL];fval |= SP2[(work >> 24) & 0x3fL];right ^= fval;}right = (right << 31) | (right >> 1);work = (leftt ^ right) & 0xaaaaaaaaL;leftt ^= work;right ^= work;leftt = (leftt << 31) | ( leftt >> 1);work = ((leftt >> 8) ^ right) & 0x00ff00ffL;right ^= work;leftt ^= (work << 8);work = ((leftt >> 2) ^ right) & 0x33333333L;right ^= work;leftt ^= (work << 2);work = ((right >> 16) ^ leftt) & 0x0000ffffL;leftt ^= work;right ^= (work << 16);work = ((right >> 4) ^ leftt) & 0x0f0f0f0fL;leftt ^= work;right ^= (work << 4);*block++ = right;*block = leftt;return;}// -----------------------------------------------------------------------// Initial of static data members. These data will be used by all the// instances of class,and can not be changed.// ----------------------------------------------------------------------- unsigned char DES::Df_Key[24] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67 }; unsigned short DES::bytebit[8] = {0200, 0100, 040, 020, 010, 04, 02, 01 };unsigned long DES::bigbyte[24] = {0x800000L, 0x400000L, 0x200000L, 0x100000L,0x80000L, 0x40000L, 0x20000L, 0x10000L,0x8000L, 0x4000L, 0x2000L, 0x1000L,0x800L, 0x400L, 0x200L, 0x100L,0x80L, 0x40L, 0x20L, 0x10L,0x8L, 0x4L, 0x2L, 0x1L }; unsigned char DES::pc1[56] = {56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17,9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35,62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21,13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3 }; unsigned char DES::totrot[16] = {1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28 }; unsigned char DES::pc2[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 }; unsigned long DES::SP1[64] = {0x01010400L, 0x00000000L, 0x00010000L, 0x01010404L,0x01010004L, 0x00010404L, 0x00000004L, 0x00010000L,0x00000400L, 0x01010400L, 0x01010404L, 0x00000400L,0x01000404L, 0x01010004L, 0x01000000L, 0x00000004L,0x00000404L, 0x01000400L, 0x01000400L, 0x00010400L,0x00010400L, 0x01010000L, 0x01010000L, 0x01000404L,0x00010004L, 0x01000004L, 0x01000004L, 0x00010004L,0x00000000L, 0x00000404L, 0x00010404L, 0x01000000L,0x00010000L, 0x01010404L, 0x00000004L, 0x01010000L,0x01010400L, 0x01000000L, 0x01000000L, 0x00000400L,0x01010004L, 0x00010000L, 0x00010400L, 0x01000004L,0x00000400L, 0x00000004L, 0x01000404L, 0x00010404L,0x01010404L, 0x00010004L, 0x01010000L, 0x01000404L,0x01000004L, 0x00000404L, 0x00010404L, 0x01010400L,0x00000404L, 0x01000400L, 0x01000400L, 0x00000000L,0x00010004L, 0x00010400L, 0x00000000L, 0x01010004L }; unsigned long DES::SP2[64] = {0x80108020L, 0x80008000L, 0x00008000L, 0x00108020L,0x00100000L, 0x00000020L, 0x80100020L, 0x80008020L,0x80000020L, 0x80108020L, 0x80108000L, 0x80000000L,0x80008000L, 0x00100000L, 0x00000020L, 0x80100020L,0x00108000L, 0x00100020L, 0x80008020L, 0x00000000L,0x80000000L, 0x00008000L, 0x00108020L, 0x80100000L,0x00100020L, 0x80000020L, 0x00000000L, 0x00108000L,0x00008020L, 0x80108000L, 0x80100000L, 0x00008020L,0x00000000L, 0x00108020L, 0x80100020L, 0x00100000L,0x80008020L, 0x80100000L, 0x80108000L, 0x00008000L,0x80100000L, 0x80008000L, 0x00000020L, 0x80108020L,0x00108020L, 0x00000020L, 0x00008000L, 0x80000000L,0x00008020L, 0x80108000L, 0x00100000L, 0x80000020L,0x00100020L, 0x80008020L, 0x80000020L, 0x00100020L,0x00108000L, 0x00000000L, 0x80008000L, 0x00008020L,0x80000000L, 0x80100020L, 0x80108020L, 0x00108000L }; unsigned long DES::SP3[64] = {0x00000208L, 0x08020200L, 0x00000000L, 0x08020008L,0x08000200L, 0x00000000L, 0x00020208L, 0x08000200L,0x00020008L, 0x08000008L, 0x08000008L, 0x00020000L,0x08020208L, 0x00020008L, 0x08020000L, 0x00000208L,0x08000000L, 0x00000008L, 0x08020200L, 0x00000200L,0x00020200L, 0x08020000L, 0x08020008L, 0x00020208L,0x08000208L, 0x00020200L, 0x00020000L, 0x08000208L,0x00000008L, 0x08020208L, 0x00000200L, 0x08000000L,0x08020200L, 0x08000000L, 0x00020008L, 0x00000208L,0x00020000L, 0x08020200L, 0x08000200L, 0x00000000L,0x00000200L, 0x00020008L, 0x08020208L, 0x08000200L,0x08000008L, 0x00000200L, 0x00000000L, 0x08020008L,0x08000208L, 0x00020000L, 0x08000000L, 0x08020208L,0x00000008L, 0x00020208L, 0x00020200L, 0x08000008L,0x08020000L, 0x08000208L, 0x00000208L, 0x08020000L,0x00020208L, 0x00000008L, 0x08020008L, 0x00020200L }; unsigned long DES::SP4[64] = {0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,0x00802080L, 0x00800081L, 0x00800001L, 0x00002001L,0x00000000L, 0x00802000L, 0x00802000L, 0x00802081L,0x00000081L, 0x00000000L, 0x00800080L, 0x00800001L,0x00000001L, 0x00002000L, 0x00800000L, 0x00802001L,0x00000080L, 0x00800000L, 0x00002001L, 0x00002080L,0x00800081L, 0x00000001L, 0x00002080L, 0x00800080L,0x00002000L, 0x00802080L, 0x00802081L, 0x00000081L,0x00800080L, 0x00800001L, 0x00802000L, 0x00802081L,0x00000081L, 0x00000000L, 0x00000000L, 0x00802000L,0x00002080L, 0x00800080L, 0x00800081L, 0x00000001L,0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,0x00802081L, 0x00000081L, 0x00000001L, 0x00002000L,0x00800001L, 0x00002001L, 0x00802080L, 0x00800081L,0x00002001L, 0x00002080L, 0x00800000L, 0x00802001L,0x00000080L, 0x00800000L, 0x00002000L, 0x00802080L }; unsigned long DES::SP5[64] = {0x00000100L, 0x02080100L, 0x02080000L, 0x42000100L,0x00080000L, 0x00000100L, 0x40000000L, 0x02080000L,0x40080100L, 0x00080000L, 0x02000100L, 0x40080100L,0x42000100L, 0x42080000L, 0x00080100L, 0x40000000L,0x02000000L, 0x40080000L, 0x40080000L, 0x00000000L,0x40000100L, 0x42080100L, 0x42080100L, 0x02000100L,0x42080000L, 0x40000100L, 0x00000000L, 0x42000000L,0x02080100L, 0x02000000L, 0x42000000L, 0x00080100L,0x00080000L, 0x42000100L, 0x00000100L, 0x02000000L,0x40000000L, 0x02080000L, 0x42000100L, 0x40080100L,0x02000100L, 0x40000000L, 0x42080000L, 0x02080100L,0x40080100L, 0x00000100L, 0x02000000L, 0x42080000L,0x42080100L, 0x00080100L, 0x42000000L, 0x42080100L,0x02080000L, 0x00000000L, 0x40080000L, 0x42000000L,0x00080100L, 0x02000100L, 0x40000100L, 0x00080000L,0x00000000L, 0x40080000L, 0x02080100L, 0x40000100L }; unsigned long DES::SP6[64] = {0x20000010L, 0x20400000L, 0x00004000L, 0x20404010L,0x20400000L, 0x00000010L, 0x20404010L, 0x00400000L,0x20004000L, 0x00404010L, 0x00400000L, 0x20000010L,0x00400010L, 0x20004000L, 0x20000000L, 0x00004010L,0x00000000L, 0x00400010L, 0x20004010L, 0x00004000L,0x00404000L, 0x20004010L, 0x00000010L, 0x20400010L,0x20400010L, 0x00000000L, 0x00404010L, 0x20404000L,0x00004010L, 0x00404000L, 0x20404000L, 0x20000000L,0x20004000L, 0x00000010L, 0x20400010L, 0x00404000L,0x20404010L, 0x00400000L, 0x00004010L, 0x20000010L,0x00400000L, 0x20004000L, 0x20000000L, 0x00004010L,0x20000010L, 0x20404010L, 0x00404000L, 0x20400000L,0x00404010L, 0x20404000L, 0x00000000L, 0x20400010L,0x00000010L, 0x00004000L, 0x20400000L, 0x00404010L,0x00004000L, 0x00400010L, 0x20004010L, 0x00000000L,0x20404000L, 0x20000000L, 0x00400010L, 0x20004010L }; unsigned long DES::SP7[64] = {0x00200000L, 0x04200002L, 0x04000802L, 0x00000000L,0x00000800L, 0x04000802L, 0x00200802L, 0x04200800L,0x04200802L, 0x00200000L, 0x00000000L, 0x04000002L,0x00000002L, 0x04000000L, 0x04200002L, 0x00000802L,0x04000800L, 0x00200802L, 0x00200002L, 0x04000800L,0x04000002L, 0x04200000L, 0x04200800L, 0x00200002L,0x04200000L, 0x00000800L, 0x00000802L, 0x04200802L,0x00200800L, 0x00000002L, 0x04000000L, 0x00200800L,0x04000000L, 0x00200800L, 0x00200000L, 0x04000802L,0x04000802L, 0x04200002L, 0x04200002L, 0x00000002L,0x00200002L, 0x04000000L, 0x04000800L, 0x00200000L,0x04200800L, 0x00000802L, 0x00200802L, 0x04200800L,0x00000802L, 0x04000002L, 0x04200802L, 0x04200000L,0x00200800L, 0x00000000L, 0x00000002L, 0x04200802L,0x00000000L, 0x00200802L, 0x04200000L, 0x00000800L,0x04000002L, 0x04000800L, 0x00000800L, 0x00200002L }; unsigned long DES::SP8[64] = {0x10001040L, 0x00001000L, 0x00040000L, 0x10041040L,0x10000000L, 0x10001040L, 0x00000040L, 0x10000000L,0x00040040L, 0x10040000L, 0x10041040L, 0x00041000L,0x10041000L, 0x00041040L, 0x00001000L, 0x00000040L,0x10040000L, 0x10000040L, 0x10001000L, 0x00001040L,0x00041000L, 0x00040040L, 0x10040040L, 0x10041000L,0x00001040L, 0x00000000L, 0x00000000L, 0x10040040L,0x10000040L, 0x10001000L, 0x00041040L, 0x00040000L,0x00041040L, 0x00040000L, 0x10041000L, 0x00001000L,0x00000040L, 0x10040040L, 0x00001000L, 0x00041040L,0x10001000L, 0x00000040L, 0x10000040L, 0x10040000L,0x10040040L, 0x10000000L, 0x00040000L, 0x10001040L,0x00000000L, 0x10041040L, 0x00040040L, 0x10000040L,0x10040000L, 0x10001000L, 0x10001040L, 0x00000000L,0x10041040L, 0x00041000L, 0x00041000L, 0x00001040L,0x00001040L, 0x00040040L, 0x10000000L, 0x10041000L };。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
北京工业大学网络与信息安全概论学院:专业:指导老师:姓名:学号:目录目录 (2)一、DES算法的基本原理 (3)1.1背景介绍 (3)1.2加密原理 (3)二、DES算法的详细步骤 (4)2.1加密详细步骤 (4)2.2压缩置换到56位 (5)2.3 C0和D0的分类 (6)2.4循环左移 (6)2.5压缩置换 (7)三、DES算法的实现 (7)3.1详细设计 (8)3.1.2加密/解密文件的预览 (8)3.2文件的加密/解密 (9)3.3系统测试 (11)3.4总结 (14)一、DES算法的基本原理1.1背景介绍1977年1月,美国政府颁布:采纳IBM公司设计的方案作为非机密数据的正式数据加密标准(DES-Data Encryption Standard)。
DES (Data Encryption Standard),是IBM在上个世纪70年代开发的单密钥对称加解密算法。
该算法利用一个56+8奇偶校验位(第8, 16, 24, 32, 40, 48, 56, 64位)=64位的密钥对以64位为单位的块数据进行加解密。
1.2加密原理DES算法是这样工作的:如Mode为加密,则用Key 去把数据Data进行加密,生成Data的密码形式(64位)作为DES的输出结果;如Mode为解密,则用Key去把密码形式的数据Data解密,还原为Data的明码形式(64位)作为DES的输出结果。
在通信网络的两端,双方约定一致的Key,在通信的源点用Key对核心数据进行DES加密,然后以密码形式在公共通信网(如电话网)中传输到通信网络的终点,数据到达目的地后,用同样的Key对密码数据进行解密,便再现了明码形式的核心数据。
这样,便保证了核心数据(如PIN、MAC等)在公共通信网中传输的安全性和可靠性。
通过定期在通信网络的源端和目的端同时改用新的Key,便能更进一步提高数据的保密性,这正是现在金融交易网络的流行做法。
二、DES算法的详细步骤2.1加密详细步骤a.明文先P置换分成L0 和R0。
b.R0通过扩展置换E从32位扩展为48位。
c.扩展后与K1异或。
d.异或结果通过S盒子转换成32位。
e.这32位再通过P置换输出32位。
f.最后,P盒置换的结果与左半部分进行异或运算,然后将左右两部分交换,之后进入下一轮迭代。
g.在完成完全相同的16轮运算后,将得到的两部分数据合在一起,将L16与R16的位置交换,再经过一个末置换函数IP-1即可得到64位的密文。
图1为DES算法的理论图解:图1 DES加密算法流程2.2压缩置换到56位通过压缩置换后64位的密钥中的奇偶校验位(第8, 16, 24, 32, 40, 48, 56, 64位)就会被去掉。
对K(64位)使用PC-1(8×7)进行置换,去掉了8个校验位。
表1 密钥置换函数PC-1(8x7)PC-157 49 41 33 25 1791 58 50 42 34 26 1810 2 59 51 43 35 2719 11 3 60 52 44 3663 55 47 39 31 23 157 62 54 46 38 30 2214 6 61 53 45 37 2921 13 5 28 20 12 42.3 C0和D0的分类经过PC-1置换后,将其置换的输出再分为前28位C0和后28位D0两部分。
图2 密钥置换输出的分法2.4循环左移再将C0和D0两部分按照下面步骤进行16轮的循环左移。
迭代顺序 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 左移位数 1 1 2 2 2 2 2 2 1 2 2 2 2 2 2 1 C1和D1分别为C0和D0左移1位……C3和D3分别为C2和D2左移2位……C16和D16分别为C15和D15左移1位。
2.5压缩置换进行一轮循环左移,就按照表4进行压缩置换,得到一个子密钥。
即置换后的输出数据的位数要比置换前输入的位数要少,原来的8行7列共56位数据被压缩成8行6列48位数据。
在压缩置换过程中,第9、18、22、25、35、38、43、54共8位数据被丢掉。
最终得到所有16个子密钥,每个48位。
置换过程如图3所示。
图3 子密钥Kn的产生Kn(48位) = PC-2( CnDn(56位) )三、DES算法的实现采用MFC实现DES加密算法。
可以对导入的文档实现加密解密,加密或解密后的文件存储路径可以自定义。
图4是主界面:图4 系统主界面如果输入的密钥长度大于8,程序自动启动3重DES加密算法。
用户可以自动设置加密/解密后存储文件的路径。
也可以在不打开文件的情况下预览加密/解密前后的文件内容。
3.1详细设计3.1.1文件的选择与存储打开程序后,首先要选择加密/解密的文件,图4中的和这两个按钮可以实现这个功能,文件载入后设置了密钥,即可实现对文件的加密/解密。
主要是用CFileDialog实现的。
CFileDialog FileDlg( TRUE, NULL, NULL, OFN_HIDEREADONLY, szFilter );3.1.2加密/解密文件的预览用户可以在不打开加密/解密文件的情况下,对文件的内容进行预览。
界面中的和按钮来实现这个功能。
核心代码如下:CString strText = ""; CString szLine = ""; CStdioFile file;file.Open(m_FileEncryptOut,CFile::modeRead);while( file.ReadString( szLine ) ){strText += szLine; }AfxMessageBox(strText); file.Close();3.2文件的加密/解密对于文件的加密和解密是在一个定义时没有制定大小的缓冲区里面进行的。
缓冲区的大小是由读入文件的大小决定的。
但是它的大小总是8的倍数,当读入数据的大小不是8的整数倍时,它的大小总比读入的文件要大一点点。
len=_lread(fh_in,databuf,BUFSIZE);//返回值为读入文件的数据大小len = ((len+7)>>3)<<3;//将len变为8的倍数当输入的密钥大于8位时,系统自动启动3重DES加密算法。
if( !Is3DES ){ // 1次DESfor(int i=0,j=len>>3; i<j; ++i){DES(Out,In,&SubKey[0],ENCRYPT);Out += 8; In += 8;}}else{ // 3次DES E-D-Efor(int i=0,j=len>>3; i<j; ++i){DES(Out,In, &SubKey[0],ENCRYPT);DES(Out,Out,&SubKey[1],DECRYPT);DES(Out,Out,&SubKey[0],ENCRYPT);Out += 8; In += 8;}}同样的,在解密的时候,若输入的密钥大于8位时,系统自动启动3重DES 算法。
加密和解密算法主要实现都是DES(char Out[8],char In[8],const PSubKey pSubKey,bool Type)函数来实现。
其中Type—ENCRYPT:加密,DECRYPT:解密,文件加密还是解密就看Type的值。
核心代码如下:UpdateData(true);HFILE fh_out,fh_in;//输入输出文件句柄fh_in=_lopen(m_FileEncrypt,OF_READ);fh_out=_lcreat(m_FileEncryptOut,0);long len;// 读取明文到缓冲区while( (len=_lread(fh_in,databuf,BUFSIZE)) >0 ){I=len%8;//对明文长度求余// 设置子密钥if(m_KeyEncrypt.GetLength()>=16)m_KeyEncrypt=m_KeyEncrypt.Left(16);m_des.SetSubKey(m_KeyEncrypt);// 将缓冲区长度变为8的倍数len = ((len+7)>>3)<<3;// 在缓冲区中加密m_des.Encrypt(databuf,databuf,len);// 将密文写入输出文件if(I==0)_lwrite(fh_out,databuf,len);else_lwrite(fh_out,databuf,len-8+I);}_lclose(fh_in);_lclose(fh_out);解密过程与加密过程一样,只不过解密过程调用的函数是m_des.Decrypt()。
加密的m_des.encrypt()与解密的m_des.Decrypt()这两个函数都是通过调用DES()函数来实现对文件的加密解密的。
值得注意的是,当明文或者是要解密的密文的长度不是8的倍数时,缓冲区这个时候的长度总是比输入的实际长度要大一些,这样缓冲区中多出来的部分默认值是0,他们也会被加密或者解密。
所以每做完一次加密或解密时,总要判断明文的长度是否为8的倍数,如果不是在存储加密/解密后的文件时,应该去掉这些多余的部分。
if(I==0)_lwrite(fh_out,databuf,len);else_lwrite(fh_out,databuf,len-8+I);3.3系统测试由于加密和解密的过程类似,所以我们在这里仅对加密过程进行测试。
在一个名为“test.txt”的文本文档里面输入“Who am I?”,对系统的加密功能进行测试,密钥为“12”。
图5,图6,图7为测试后的截图。
图5 点击加密按钮后的提示图6 点击显示密文按钮后的提示图7 点击显示明文按钮后的提示当你在没有选择任何文档或者没有填写既要的情况下点击加密按钮或者想查看明文/密文时,系统会报错。
如图8,图9和图10所示。
图8 直接点击加密按钮后的提示图9 直接点击显示密文按钮后的提示图9 直接点击显示明文按钮后的提示3.4总结在理解了DES算法的基本原理后,对DES算法的基本原理和详细步骤进行的阐述。
通过几天的努力,用MFC实现了DES算法的加密解密过程。
但是程序界面有待改进,可以在实现了加密解密的基础上直接现实出明文和密文。
其他地方也需要美化。