DES加密解密C++

合集下载

Python常用base64md5aesdescrc32加密解密方法汇总

Python常用base64md5aesdescrc32加密解密方法汇总

Python常⽤base64md5aesdescrc32加密解密⽅法汇总1.base64Python内置的base64模块可以实现base64、base32、base16、base85、urlsafe_base64的编码解码,python 3.x通常输⼊输出都是⼆进制形式,2.x可以是字符串形式。

base64模块的base64编码、解码调⽤了binascii模块,binascii模块中的b2a_base64()函数⽤于base64编码,binascii模块中的a2b_base64()函数⽤于base64解码。

>>>import base64>>> s = 'hello,word!'>>> base64.b64encode(bytes(s,'ascii')) #base64编码,编码的字符串必须是⼆进制形式的b'aGVsbG8sd29yZCE='>>> base64.b64decode(b'aGVsbG8sd29yZCE=') #base64解码b'hello,word!'2.md5Python2.x中有md5模块,此模块调⽤了hashlib模块,python3.x已中将md5取掉,直接通过调⽤hashlib模块来进⾏md5。

Python2.x可以直接使⽤unicode字符,但3.x中必须使⽤⼆进制字节串。

>>> import hashlib>>> m = hashlib.md5()>>> m.update(b'hello,word!')>>> m.hexdigest()'9702d6722a0901398efd4ecb3a20423f'注意:每调⽤⼀次update(s),相当于给md5对象m增加了s。

DES算法的C语言实现

DES算法的C语言实现

DES算法的C语⾔实现利⽤C语⾔实现DES算法,分组密码原理过程很简单,但是在写的过程中检查了好久才发现错误原因,主要有两点:1.在加密过程16轮迭代过程中,最后⼀轮迭代运算后的结果并没有进⾏交换,即C=IP-1(R16,L16),这样做的⽬的是为了加密解密使⽤同⼀个算法2.在S盒的过程中,移位后应该加括号,否则+的优先级⾼于<<,会出错,下⾯是算法源码:1 #include "des.h"2 #include <stdio.h>3 #include <stdlib.h>45const unsigned char IP_table[64] = {658, 50, 42, 34, 26, 18, 10, 2,760, 52, 44, 36, 28, 20, 12, 4,862, 54, 46, 38, 30, 22, 14, 6,964, 56, 48, 40, 32, 24, 16, 8,1057, 49, 41, 33, 25, 17, 9, 1,1159, 51, 43, 35, 27, 19, 11, 3,1261, 53, 45, 37, 29, 21, 13, 5,1363, 55, 47, 39, 31, 23, 15, 714 };1516const unsigned char IPR_table[64] = {1740, 8, 48, 16, 56, 24, 64, 32,1839, 7, 47, 15, 55, 23, 63, 31,1938, 6, 46, 14, 54, 22, 62, 30,2037, 5, 45, 13, 53, 21, 61, 29,2136, 4, 44, 12, 52, 20, 60, 28,2235, 3, 43, 11, 51, 19, 59, 27,2334, 2, 42, 10, 50, 18, 58, 26,2433, 1, 41, 9, 49, 17, 57, 2525 };2627const unsigned char E_table[48] = {2832, 1, 2, 3, 4, 5,294, 5, 6, 7, 8, 9,308, 9, 10, 11, 12, 13,3112, 13, 14, 15, 16, 17,3216, 17, 18, 19, 20, 21,3320, 21, 22, 23, 24, 25,3424, 25, 26, 27, 28, 29,3528, 29, 30, 31, 32, 136 };3738const unsigned char P_table[32] = {3916, 7, 20, 21, 29, 12, 28, 17,401, 15, 23, 26, 5, 18, 31, 10,412, 8, 24, 14, 32, 27, 3, 9,4219, 13, 30, 6, 22, 11, 4, 2543 };4445const unsigned char PC1_table[56] = {4657, 49, 41, 33, 25, 17, 9,471, 58, 50, 42, 34, 26, 18,4810, 2, 59, 51, 43, 35, 27,4919, 11, 3, 60, 52, 44, 36,5063, 55, 47, 39, 31, 23, 15,517, 62, 54, 46, 38, 30, 22,5214, 6, 61, 53, 45, 37, 29,5321, 13, 5, 28, 20, 12, 454 };5556const unsigned char LOOP_table[16] = {571, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 158 };5960const unsigned char PC2_table[48] = {6114, 17, 11, 24, 1, 5,623, 28, 15, 6, 21, 10,6323, 19, 12, 4, 26, 8,6416, 7, 27, 20, 13, 2,6541, 52, 31, 37, 47, 55,6630, 40, 51, 45, 33, 48,6744, 49, 39, 56, 34, 53,6846, 42, 50, 36, 29, 3269 };7071const unsigned char sbox[8][4][16] = {72// S17314, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,740, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,754, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,7615, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13,77//S27815, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,793, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,800, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,8113, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9,82//S38310, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,8413, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,8513, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,861, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12,87//S4887, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,8913, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,9010, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,913, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14,92//S5932, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,9414, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,954, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,9611, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3,97//S69812, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,9910, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,1009, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,1014, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13,102//S71034, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,10413, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,1051, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,1066, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12,107//S810813, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,1091, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,1107, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,1112, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11112 };113114void ByteToBit(unsigned char* out, const unsigned char* in, const int bits){115for(int i=0;i<bits;i++)116out[i]=(in[i/8]>>(7-i%8))&1;117 }118119void BitToByte(unsigned char* out, const unsigned char* in, const int bits){120 memset(out, 0, (bits + 7) / 8);121for(int i=0;i<bits;i++)122out[i/8]|=in[i]<<(7-i%8);123 }124125void Transform(unsigned char* out,const unsigned char* in, const unsigned char* table, const int len){ 126 unsigned char tmp[64] = {0};127for (int i = 0; i < len; i++)128 tmp[i] = in[table[i] - 1];129 memcpy(out, tmp, len);130 }131132void RotateL(unsigned char* in, const int len, int loop){133static unsigned char tmp[64];134 memcpy(tmp, in, len);135 memcpy(in, in + loop, len - loop);136 memcpy(in + len - loop, tmp, loop);137 }138139static unsigned char subKey[16][48] = { 0 };140void setKey(const unsigned char* in){141char key[64] = { 0 };142 ByteToBit(key, in, 64);143char temp[56]={0};144 Transform(temp, key, PC1_table, 56);145for(int i=0;i<16;i++){146 RotateL(temp, 28, LOOP_table[i]);147 RotateL(temp + 28, 28, LOOP_table[i]);148 Transform(subKey[i], temp, PC2_table, 48);149 }150 }151152void xor(unsigned char* in1,const unsigned char* in2,int len){153for(int i=0;i<len;i++)154 in1[i]^=in2[i];155 }156157void sbox_exchange(unsigned char* out,const unsigned char* in){158char row, column;159for (int i = 0; i < 8; i++){160char num = 0;161 row = (in[6 * i]<<1)+ in[6 * i + 5];162 column = (in[6 * i + 1] << 3) + (in[6 * i + 2] << 2) + (in[6 * i + 3] << 1) + in[6 * i + 4]; 163 num = sbox[i][row][column];164for (int j = 0; j < 4; j++)165 {166out[4 * i + j] = (num >> (3 - j)) & 1;167 }168 }169 }170171void F_func(unsigned char* out,const unsigned char* in,unsigned char* subKey){172 unsigned char temp[48]={0};173 unsigned char res[32]={0};174 Transform(temp, in, E_table, 48);175 xor(temp,subKey,48);176 sbox_exchange(res,temp);177 Transform(out, res, P_table, 32);178 }179180void encryptDES(unsigned char* out,const unsigned char* in, const unsigned char* key){ 181 unsigned char input[64] = { 0 };182 unsigned char output[64] = { 0 };183 unsigned char tmp[64] = { 0 };184 ByteToBit(input, in, 64);185 Transform(tmp, input, IP_table, 64);186char* Li = &tmp[0], *Ri = &tmp[32];187 setKey(key);188for(int i=0;i<16;i++){189char temp[32]={0};190 memcpy(temp,Ri,32);191 F_func(Ri, Ri,subKey[i]);192 xor(Ri, Li, 32);193 memcpy(Li,temp,32);194 }195 RotateL(tmp, 64, 32);//the input is LR,output is RL196 Transform(output, tmp, IPR_table, 64);197 BitToByte(out, output,64);198 }199200void decryptDES(unsigned char* out,const unsigned char* in, const unsigned char* key){ 201 unsigned char input[64] = { 0 };202 unsigned char output[64] = { 0 };203 unsigned char tmp[64] = { 0 };204 ByteToBit(input, in, 64);205 Transform(tmp, input, IP_table, 64);206char* Li = &tmp[0], *Ri = &tmp[32];207 setKey(key);208 RotateL(tmp, 64, 32);209for (int i = 0; i < 16; i++){210char temp[32] = { 0 };211 memcpy(temp, Li, 32);212 F_func(Li, Li,subKey[15 - i]);213 xor(Li, Ri, 32);214 memcpy(Ri, temp, 32);215 }216 Transform(output, tmp, IPR_table, 64);217 BitToByte(out, output, 64);218 }。

DES的加密解密流程

DES的加密解密流程
• 对每个 盒,6比特输入中的第 和第 比特 对每个S盒 比特输入中的第1和第 比特输入中的第 和第6比特 组成的二进制数对应的十进制数用来确定 中间4位二进制数对应的十进制数用来 行,中间 位二进制数对应的十进制数用来 确定列,相应行、列位置的十进制数的4位 确定列,相应行、列位置的十进制数的 位 二进制数表示作为输出。 二进制数表示作为输出。 • 例如 盒的输入为 例如S1盒的输入为 盒的输入为011001,则行数和列数 , 的二进制表示分别是01和 的二进制表示分别是 和1100,即第 行和 ,即第1行和 盒的第1行和第 第12列,S1盒的第 行和第 列的十进制 列 盒的第 行和第12列的十进制 数为9, 位二进制数表示为1001,所以 数为 ,用4位二进制数表示为 位二进制数表示为 , S1盒的输出为 盒的输出为1001。 盒的输出为 。
Feistel 结构图
Feistel结构定义 Feistel结构定义
• 加密: Li = Ri-1; Ri = Li-1⊕F(Ri-1,Ki) • 解密: Ri-1 = Li Li-1 = Ri⊕F(Ri-1,Ki) = Ri⊕F(Li,Ki)
Feistel 的加密 和解密
DES算法的基本结构
置换表(P表)
子密钥的产生
置换选择1
置换选择2和循环左移次数
初始置换(IP)
逆初始置换(IP-1)
DES每轮变换 Li = Ri-1 Ri = Li-1⊕F(Ri-1,Ki) ⊕
F函数
Expansion: 32 S-box: 6 4 Permutation 48
扩展/置换表(ox)
S盒(S-box)(续)
S盒(S-box)(续)

DES加解密算法C语言源代码

DES加解密算法C语言源代码

DES加解密算法C语言源代码以下是一个实现DES加解密算法的C语言源代码,包含了加密和解密函数。

请注意,这个代码只是为了演示DES算法的工作原理,并不是一个完整的、安全的加密算法实现。

```c#include <stdio.h>#include <stdint.h>typedef structuint8_t key[8];uint8_t subkeys[16][6];} DESKey;void generateSubkeys(uint8_t* key, uint8_t subkeys[16][6]) //略过子密钥生成算法的具体实现//这里只是假设生成的子密钥都是随机的,实际生成过程要更复杂for (int i = 0; i < 16; i++)for (int j = 0; j < 6; j++)subkeys[i][j] = (i+j) % 256;}}void DES(uint8_t* input, uint8_t key[8], uint8_t* output, int encrypt)//略过DES加密算法的具体实现DESKey desKey;for (int i = 0; i < 8; i++)desKey.key[i] = key[i];}generateSubkeys(key, desKey.subkeys);//这里只是假设输入输出是8字节长,实际上可以支持任意长度//执行加解密操作if (encrypt)printf("Encrypting: ");} elseprintf("Decrypting: ");}for (int i = 0; i < 8; i++)output[i] = encrypt ? input[i] ^ desKey.subkeys[0][i%6] : input[i] ^ desKey.subkeys[15][i%6];printf("%02X ", output[i]);}printf("\n");int maiuint8_t input[8] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0};uint8_t key[8] = {0xA1, 0xB2, 0xC3, 0xD4, 0xE5, 0xF6, 0x07,0x08};uint8_t output[8];DES(input, key, output, 1);DES(output, key, output, 0);return 0;```在这个代码中,`generateSubkeys` 函数用于生成 16 个子密钥,之后分别在加密和解密函数 `DES` 中使用。

C语言加密与解密算法

C语言加密与解密算法

C语言加密与解密算法在计算机科学与信息安全领域,加密与解密算法起着至关重要的作用。

加密算法用于将原始数据转换为不可读的密文,而解密算法则用于将密文还原为可读的原始数据。

C语言是一种常用的编程语言,具备高效性和灵活性,适用于加密与解密算法的开发。

本文将介绍几种常用的C语言加密与解密算法。

一、凯撒密码算法凯撒密码算法是一种最简单的替换加密算法,通过将字母按照固定的偏移量进行替换来实现加密与解密。

以下是一个简单的C语言凯撒密码实现例子:```c#include <stdio.h>void caesarEncrypt(char* message, int key) {int i = 0;while (message[i] != '\0') {if (message[i] >= 'a' && message[i] <= 'z') {message[i] = (message[i] - 'a' + key) % 26 + 'a';} else if (message[i] >= 'A' && message[i] <= 'Z') {message[i] = (message[i] - 'A' + key) % 26 + 'A';}i++;}}void caesarDecrypt(char* message, int key) {int i = 0;while (message[i] != '\0') {if (message[i] >= 'a' && message[i] <= 'z') {message[i] = (message[i] - 'a' - key + 26) % 26 + 'a'; } else if (message[i] >= 'A' && message[i] <= 'Z') {message[i] = (message[i] - 'A' - key + 26) % 26 + 'A'; }i++;}}int main() {char message[] = "Hello, World!";int key = 3;printf("Original message: %s\n", message);caesarEncrypt(message, key);printf("Encrypted message: %s\n", message);caesarDecrypt(message, key);printf("Decrypted message: %s\n", message);return 0;}```以上程序演示了凯撒密码的加密与解密过程,通过指定偏移量实现对消息的加密与解密。

DES 加解密算法(java和c#版)

DES 加解密算法(java和c#版)

/** java 版的* <p>Title: DES 加解密算法</p>* <p>Description: DES 加解密算法</p>* <p>Copyright: Copyright (c) 2004</p>* <p>Company: Aspire Corp</p>* @author zhangji* @version 1.0*/import java.security.*;import javax.crypto.*;public class DES {private static String strDefaultKey = "hnzt";private Cipher encryptCipher = null;private Cipher decryptCipher = null;/*** 将byte数组转换为表示16进制值的字符串,* 如:byte[]{8,18}转换为:0813,* 和public static byte[] hexStr2ByteArr(String strIn)* 互为可逆的转换过程* @param arrB 需要转换的byte数组* @return 转换后的字符串* @throws Exception 本方法不处理任何异常,所有异常全部抛出*/public static String byteArr2HexStr(byte[] arrB)throws Exception{int iLen = arrB.length;//每个byte用两个字符才能表示,所以字符串的长度是数组长度的两倍StringBuffer sb = new StringBuffer(iLen * 2);for (int i = 0; i < iLen; i++){int intTmp = arrB[i];//把负数转换为正数while (intTmp < 0){intTmp = intTmp + 256;}//小于0F的数需要在前面补0if (intTmp < 16){sb.append("0");}sb.append(Integer.toString(intTmp, 16));}return sb.toString();}/*** 将表示16进制值的字符串转换为byte数组,* 和public static String byteArr2HexStr(byte[] arrB)* 互为可逆的转换过程* @param strIn 需要转换的字符串* @return 转换后的byte数组* @throws Exception 本方法不处理任何异常,所有异常全部抛出* @author <a href="mailto:zhangji@">ZhangJi</a> */public static byte[] hexStr2ByteArr(String strIn)throws Exception{byte[] arrB = strIn.getBytes();int iLen = arrB.length;//两个字符表示一个字节,所以字节数组长度是字符串长度除以2byte[] arrOut = new byte[iLen / 2];for (int i = 0; i < iLen; i = i + 2){String strTmp = new String(arrB, i, 2);arrOut[i / 2] = (byte) Integer.parseInt(strTmp, 16);}return arrOut;}/*** 默认构造方法,使用默认密钥* @throws Exception*/public DES()throws Exception{this(strDefaultKey);}/*** 指定密钥构造方法* @param strKey 指定的密钥* @throws Exception*/public DES(String strKey)throws Exception{Security.addProvider(new com.sun.crypto.provider.SunJCE()); Key key = getKey(strKey.getBytes());encryptCipher = Cipher.getInstance("DES");encryptCipher.init(Cipher.ENCRYPT_MODE, key);decryptCipher = Cipher.getInstance("DES");decryptCipher.init(Cipher.DECRYPT_MODE, key);}/*** 加密字节数组* @param arrB 需加密的字节数组* @return 加密后的字节数组* @throws Exception*/public byte[] encrypt(byte[] arrB)throws Exception{return encryptCipher.doFinal(arrB);}/*** 加密字符串* @param strIn 需加密的字符串* @return 加密后的字符串* @throws Exception*/public String encrypt(String strIn)throws Exception{return byteArr2HexStr(encrypt(strIn.getBytes())); }/*** 解密字节数组* @param arrB 需解密的字节数组* @return 解密后的字节数组* @throws Exception*/public byte[] decrypt(byte[] arrB)throws Exception{return decryptCipher.doFinal(arrB);}/*** 解密字符串* @param strIn 需解密的字符串* @return 解密后的字符串* @throws Exception*/public String decrypt(String strIn)throws Exception{return new String(decrypt(hexStr2ByteArr(strIn)));}/*** 从指定字符串生成密钥,密钥所需的字节数组长度为8位* 不足8位时后面补0,超出8位只取前8位* @param arrBTmp 构成该字符串的字节数组* @return 生成的密钥* @throws ng.Exception*/private Key getKey(byte[] arrBTmp)throws Exception{//创建一个空的8位字节数组(默认值为0)byte[] arrB = new byte[8];//将原始字节数组转换为8位for (int i = 0; i < arrBTmp.length && i < arrB.length; i++) {arrB[i] = arrBTmp[i];}//生成密钥Key key = new javax.crypto.spec.SecretKeySpec(arrB, "DES"); return key;}/*** 单元测试方法* @param args*/public static void main(String[] args){String strOriginal = "1111";String strOp = "-de";// 检查入参个数if (args.length == 2 ){strOp = args[0] ;strOriginal = args[1];}else{System.out.println("Wrong Parameter count , try use \"java DES -de|-en 'the string you want to be Encrypted'\"");System.out.println("Now do Encrypt with \"1111\"");try{DES des = new DES();// 加密测试System.out.println("***** 加密测试 *****") ;des.enTest("1111");// 解密测试System.out.println("***** 解密测试 *****") ;des.deTest("0fc7648b53e54cfb");}catch (Exception ex){ex.printStackTrace();}return ;}try{if ( strOp.equals("-de")) {DES des = new DES();des.deTest(strOriginal);}else if ( strOp.equals("-en")) {DES des = new DES();des.enTest(strOriginal);}else{System.out.println("Wrong operater , try use \"java DES -de|-en 'the string you want to be Encrypted'\"");System.out.println("Now do Encrypt with \"1111\""); }}catch (Exception ex){ex.printStackTrace();}}/*** 单元测试方法,打印对指定字符串加密后的字符串*/private void enTest(String strOriginal){try{System.out.println("Plain String: " + strOriginal);String strEncrypt= encrypt(strOriginal);System.out.println("Encrypted String: " + strEncrypt);}catch (Exception ex){ex.printStackTrace();}}/*** 单元测试方法,打印对指定字符串解密后的字符串*/private void deTest(String strOriginal){try{System.out.println("Encrypted String: " + strOriginal); System.out.println("Encrypted String length = " + strOriginal.length());String strPlain = decrypt(strOriginal);System.out.println("Plain String: " + strPlain);}catch (Exception ex){ex.printStackTrace();}}}===============c#版的================using System;using System.Text;using System.IO;using System.Security.Cryptography;class Class1{static void Main(){Console.WriteLine("Encrypt String...");txtKey = "tkGGRmBErvc=";btnKeyGen();Console.WriteLine("Encrypt Key :{0}",txtKey);txtIV = "Kl7ZgtM1dvQ=";btnIVGen();Console.WriteLine("Encrypt IV :{0}",txtIV);Console.WriteLine();string txtEncrypted = EncryptString("1111");Console.WriteLine("Encrypt String : {0}",txtEncrypted);string txtOriginal = DecryptString(txtEncrypted);Console.WriteLine("Decrypt String : {0}",txtOriginal);}private static SymmetricAlgorithm mCSP;private static string txtKey;private static string txtIV;private static void btnKeyGen(){mCSP = SetEnc();byte[] byt2 = Convert.FromBase64String(txtKey);mCSP.Key = byt2;}private static void btnIVGen(){byte[] byt2 = Convert.FromBase64String(txtIV);mCSP.IV = byt2;}private static string EncryptString(string Value){ICryptoTransform ct;MemoryStream ms;CryptoStream cs;byte[] byt;ct = mCSP.CreateEncryptor(mCSP.Key, mCSP.IV);byt = Encoding.UTF8.GetBytes(Value);ms = new MemoryStream();cs = new CryptoStream(ms, ct, CryptoStreamMode.Write); cs.Write(byt, 0, byt.Length);cs.FlushFinalBlock();cs.Close();return Convert.ToBase64String(ms.ToArray());}private static string DecryptString(string Value){ICryptoTransform ct;MemoryStream ms;CryptoStream cs;byte[] byt;ct = mCSP.CreateDecryptor(mCSP.Key, mCSP.IV);byt = Convert.FromBase64String(Value);ms = new MemoryStream();cs = new CryptoStream(ms, ct, CryptoStreamMode.Write); cs.Write(byt, 0, byt.Length);cs.FlushFinalBlock();cs.Close();return Encoding.UTF8.GetString(ms.ToArray());}private static SymmetricAlgorithm SetEnc() {return new DESCryptoServiceProvider(); }}。

DES加密的算法

DES加密的算法

信息安全概论·课程设计DES加密的C语言实现目录摘要....................................................... 错误!未定义书签。

Abstract ................................................... 错误!未定义书签。

关键词..................................................... 错误!未定义书签。

1.算法描述................................................ 错误!未定义书签。

1.1加/解密算法的一般原理............................... 错误!未定义书签。

1.2加/解密机制的应用................................... 错误!未定义书签。

2.S盒设计................................................ 错误!未定义书签。

3.DES程序实例与分析...................................... 错误!未定义书签。

4.DES实例运行结果........................................ 错误!未定义书签。

5.结语.................................................... 错误!未定义书签。

6.参考文献................................................. 错误!未定义书签。

信息安全概论·课程设计DES加密的C语言实现C language achieve DES algorithm摘要DES算法是一种数据加密算法,自从1977年公布以来,一直是国际上的商用保密通信和计算机通信的最常用的加密标准。

C语言实现CBC模式DES加密

C语言实现CBC模式DES加密

C语⾔实现CBC模式DES加密#define SECTION_SIZE 8 //每段密⽂字节数,DES为8个字节64位#define GET_BIT(x,y) (x |((BYTE)0xff <<9-y) | ((BYTE)0xff >>y)) //将X的第Y位保留,其余位置1#define FORM_DWORD(p1,p2,p3,p4) ((((DWORD)p1) <<24) | (((DWORD)p2) <<16) | (((DWORD)p3) <<8) | ((DWORD)p4)) //四个字节形成⼀个双字#define FORM_BYTE(x,y) ((BYTE)((x & ((DWORD)0xffffffff << 8*(4-y)) & ((DWORD)0xffffffff >> (y-1)*8)) >>(4-y)*8))//将双字X的第Y个字节提取出来#define GET_BIT_LOW(x,y) ((x & ( (BYTE)0xff<<(8-y)) & (BYTE)0xff >> (y-1)) >> (8-y)) //拿到字节X的第Y位//#define ENCRPT //如果定义则为加密,⽆定义为解密#define CHANGE //未⽤//------------------------------------------------------------------------------------------BYTE DisPlaceIPTable[] = { 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};BYTE DisPlaceRIPTable[] = { 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};BYTE DisPlaceKEYTable[] = { 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, };BYTE MoveCount[] = { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 };BYTE PC_2[] = { 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 };BYTE E_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, 1 };BYTE 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};BYTE 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 };BYTE 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 };BYTE S4[4][16] = { 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 };BYTE 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 };BYTE 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, 6,4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 };BYTE 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 };BYTE 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 };BYTE result[] = { 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 };//---------------------------------------------------------------------------------typedef struct _BIT{BYTE a : 1;BYTE b : 1;BYTE c : 1;BYTE d : 1;BYTE e : 1;BYTE f : 1;}BIT,*PBIT;typedef struct _8_BIT{BYTE a : 1;BYTE b : 1;BYTE c : 1;BYTE d : 1;BYTE e : 1;BYTE f : 1;BYTE g : 1;BYTE h : 1;}E_BIT,*P4_BIT;LPVOID getTable(int index);DWORD data_rl(DWORD x, BYTE y, BYTE z);PBYTE SHL_Connect(PBYTE p1, PBYTE p2, int index);void ExchangeDword(PVOID p1, PVOID p2);void DisPlaceItem(PVOID fileVa, PBYTE KEY, int length);// DESEncryption.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include "windows.h"#include "myEncpy.h"int _tmain(int argc, _TCHAR* argv[]){//get plaintextHANDLE hFile = CreateFile(L"d:\\a.txt", GENERIC_ALL, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL); if (hFile == INVALID_HANDLE_VALUE){printf_s("can not create file... d:a.txt");system("pause");return0;}HANDLE hFileMapping = CreateFileMapping(hFile, 0, PAGE_READWRITE, 0, 0, L"myshare");if (hFileMapping == INVALID_HANDLE_VALUE){printf_s("can not create filemapping");system("pause");return0;}LPVOID fileVa = MapViewOfFile(hFileMapping, FILE_MAP_ALL_ACCESS, 0, 0, 0);if (fileVa == NULL){printf_s("can not get mapview");system("pause");return0;}//printf_s("%s\n", fileVa);//使⽤内存映射打开⼤⽂件//---------------------------------------------------------------//get parameter,key,subkeyBYTE KEY[8] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h' }; //定义密钥DisPlaceItem(KEY, DisPlaceKEYTable,7);PBYTE SubKey[16];BYTE C0[4] = { KEY[0], KEY[1], KEY[2], KEY[3]&0xf0 };BYTE D0[4] = { KEY[3] & 0x0f, KEY[4], KEY[5], KEY[6] };for (int i = 0; i < 16; i++){PBYTE p = SHL_Connect(C0, D0, i);DisPlaceItem(p, PC_2, 6);SubKey[i] = p; //⽣成16个⼦密钥}//-----------------// begain encrypBYTE CBC_IV[] = { 0x11, 0x32, 0x43, 0x54, 0x65, 0x76, 0x87, 0xa8 };//初始化向量未向PBYTE fileOffset =(PBYTE)fileVa; //明⽂起始位置DWORD fileSize = GetFileSize(hFile, 0); //得到明⽂⼤⼩for (DWORD index = 0; index < fileSize / SECTION_SIZE ; index ++) //⽬前只针对凑满8个字节的部分进⾏加密{fileOffset = fileOffset + index *SECTION_SIZE;//for (int i = 0; i < SECTION_SIZE; i++)//{// *(fileOffset + i) ^= CBC_IV[i];//}#ifdef CHANGEDisPlaceItem(fileOffset, DisPlaceIPTable, 8); //IP置换#endif#ifdef ENCRPTfor (int j =0; j <16; j++)#elsefor (int j = 15; j >= 0; j--){#endifBYTE L0[4], R0[6];memcpy(L0, fileOffset, 4);memcpy(R0, fileOffset + 4, 4); //分别拿到左边右边4个字节#ifdef ENCRPTif (j !=15)#elseif (j != 0)#endifmemcpy(fileOffset, R0, 4); //如果不是最后⼀次加密或者解密,则右边直接写回左边elsememcpy(fileOffset + 4, R0, 4);DisPlaceItem(R0, E_Table, 6); //扩展置换PBYTE pbyte1 = SubKey[j];for (int i = 0; i < 6; i++){R0[i] ^= pbyte1[i]; //与右边进⾏异或}//partion----------------------------------------BIT mybit[8] = {0};///////////////////////BYTE t[48]; //把6字节分为6位⼀组共8组int tIndex = 1;int rIdex = 0;for (int i = 0; i < 48; i++){BYTE a = R0[rIdex];t[i] = GET_BIT_LOW(R0[rIdex], tIndex);if (tIndex % 8 == 0){rIdex++;tIndex = 1;}else{tIndex++;}}tIndex = 0;for (int i = 0; i < 48; i+=6){mybit[tIndex].a = t[i];mybit[tIndex].b = t[i+1];mybit[tIndex].c = t[i+2];mybit[tIndex].d = t[i+3];mybit[tIndex].e = t[i+4];mybit[tIndex].f = t[i+5];tIndex++;}//此时mybit⾥⾯放着分组之后的每⼀位////////////////////////BYTE Str[4];int EIndex = 0;BYTE(*tempTable)[16] = 0;for (char i = 0; i < 8; i += 2) //根据mybit拿到表中的数并组合成str{tempTable = (BYTE(*)[16])getTable(i + 1);BYTE sum1 = tempTable[mybit[i].a*2 + mybit[i].f][mybit[i].b*8 + mybit[i].c*4 + mybit[i].d*2 + mybit[i].e];tempTable = (BYTE(*)[16])getTable(i + 2);BYTE sum2 = tempTable[mybit[i + 1].a*2 + mybit[i + 1].f][mybit[i + 1].b*8 + mybit[i + 1].c*4 + mybit[i + 1].d*2 + mybit[i + 1].e]; BYTE sum = sum1 << 4 | sum2;memcpy(Str + EIndex, &sum, 1);EIndex++;}#ifdef CHANGEDisPlaceItem(Str, result, 4); //结果与左边置换#endiffor (int i = 0; i < 4; i++){L0[i] ^= Str[i];}#ifdef ENCRPTif (j != 15)#elseif (j != 0) //将左边写到右边#endifmemcpy(fileOffset + 4, L0, 4);elsememcpy(fileOffset, L0, 4);}#ifdef CHANGEDisPlaceItem(fileOffset, DisPlaceRIPTable, 8);//IP逆置换#endif//memcpy(CBC_IV, fileOffset, 8);//-----------------------------------------------}printf_s("got it");for (int i = 0; i < 16; i++){free(SubKey[i]);}CloseHandle(hFile);CloseHandle(hFileMapping);UnmapViewOfFile(fileVa);system("pause");return0;}void DisPlaceItem(PVOID fileVa,PBYTE KEY,int length) //fileva为需要置换的内容⾸地址 key为置换表,length为输出字节数{PBYTE File = (PBYTE)fileVa;BYTE Result[8] ;memset(Result, 0xff, 8);int DisIndex = 1;for (int i = 0; i < length; i++){int bitofEach = 1;while (true){BYTE temp1 = KEY[DisIndex-1];BYTE ByteIndex = temp1 / 8;ByteIndex = temp1 % 8 == 0 ? ByteIndex -1 : ByteIndex;BYTE BitIndex = temp1- ByteIndex*8;BYTE temptemp = *(File + ByteIndex);if (bitofEach < BitIndex){temptemp = *(File + ByteIndex) << (BitIndex - bitofEach);}else if (bitofEach>BitIndex){temptemp = *(File + ByteIndex) >> (bitofEach - BitIndex);}BYTE t = GET_BIT(temptemp, bitofEach);Result[i] = Result[i] & GET_BIT(temptemp, bitofEach);if (DisIndex % 8 == 0)break;DisIndex++;bitofEach++;}DisIndex++;}memcpy(fileVa, Result, length);}PBYTE SHL_Connect(PBYTE p1, PBYTE p2, int index) //循环移位并连接{PBYTE pbyte = (PBYTE)malloc(7);DWORD d1 = FORM_DWORD(p1[0], p1[1], p1[2], p1[3]);DWORD d2 = FORM_DWORD(p2[0], p2[1], p2[2], p2[3]) <<4;d1 = data_rl(d1, MoveCount[index], 32);d2 = data_rl(d2, MoveCount[index], 32) >>4;for (int i = 0; i < 4; i++){*(p1 + i) = FORM_BYTE(d1, i + 1);*(p2 + i) = FORM_BYTE(d2, i + 1);}memcpy(pbyte, p1, 3);BYTE temp = p1[3] | p2[0];*(pbyte + 3) = temp;memcpy(pbyte + 4, p2, 3);return pbyte;}DWORD data_rl(DWORD x, BYTE y, BYTE z) //移位的实现{DWORD temp;temp = x >> (y - z );temp = temp << 4;x = x << z;x = x | temp;return x;}LPVOID getTable(int index) {switch (index){case1:return S1;break;case2:return S2;break;case3:return S3;break;case4:return S4;break;case5:return S5;break;case6:return S6;break;case7:return S7;break;case8:return S8;break;default:break;}}。

des密码算法程序c语言

des密码算法程序c语言

des密码算法程序c语言一、概述DES(数据加密标准)是一种常用的对称加密算法,它采用64位的密钥,对数据进行加密和解密。

本程序使用C语言实现DES算法,包括密钥生成、数据加密和解密等操作。

二、算法实现1.密钥生成:使用初始置换算法IP(56位)将明文转化为56位的分组,再将该分组经过一系列的逻辑函数F进行6轮处理,最终生成一个56位的密文。

其中密钥包括56位数据位和8位奇偶校验位。

2.数据加密:将需要加密的数据转化为56位的分组,再经过DES 算法处理,得到密文。

3.数据解密:将密文经过DES算法处理,还原成原始明文。

三、程序代码```c#include<stdio.h>#include<string.h>#include<stdlib.h>#include<time.h>//DES算法参数定义#defineITERATIONS6//加密轮数#defineKEY_LENGTH8//密钥长度,单位为字节#defineBLOCK_SIZE8//数据分组长度,单位为字节#definePADDINGPKCS7Padding//填充方式#defineMAX_INPUT_LENGTH(BLOCK_SIZE*2)//数据输入的最大长度//初始置换函数voidinit_permutation(unsignedcharinput[BLOCK_SIZE]){inti;for(i=0;i<BLOCK_SIZE;i++){input[i]=i;}}//逻辑函数F的定义voidlogic_function(unsignedcharinput[BLOCK_SIZE],unsigned charoutput[BLOCK_SIZE]){inti;for(i=0;i<BLOCK_SIZE;i++){output[i]=input[(i+1)%BLOCK_SIZE]^input[i]^(i+1)/BLOCK_SI ZE;}}//DES算法主函数voiddes_encrypt(unsignedchar*input,unsignedchar*output){ unsignedcharkey[KEY_LENGTH];//密钥数组unsignedchariv[BLOCK_SIZE];//初始置换的输入数组unsignedcharciphertext[MAX_INPUT_LENGTH];//密文数组unsignedcharpadding[BLOCK_SIZE];//填充数组unsignedintlength=strlen((char*)input);//数据长度(以字节为单位)unsignedintpadding_length=(length+BLOCK_SIZE-1)%BLOCK_SIZE;//需要填充的字节数unsignedintround=0;//加密轮数计数器unsignedintj=0;//数据指针,用于循环读取数据和填充数据intkey_offset=((1<<(32-KEY_LENGTH))-1)<<(32-(ITERATIONS*BLOCK_SIZE));//密钥索引值,用于生成密钥数组和填充数组的初始值unsignedintk=0;//DES算法中每个轮次的密钥索引值,用于生成每个轮次的密钥数组和填充数组的值unsignedintkplus1=(k+1)%((1<<(32-BLOCK_SIZE))-1);//DES算法中每个轮次的密钥索引值加一后的值,用于下一个轮次的密钥生成charseed[32];//使用MD5作为初始种子值生成随机数序列chartmp[MAX_INPUT_LENGTH];//临时变量数组,用于数据交换和中间计算结果存储等操作time_tt;//时间戳变量,用于生成随机数序列的种子值srand((unsignedint)time(&t));//设置随机数种子值,确保每次运行生成的随机数序列不同init_permutation(iv);//初始置换操作,将输入数据转化为56位分组(需要重复填充时)或一个随机的分组(不需要重复填充时)memcpy(key,key_offset,sizeof(key));//将初始化的密钥数组复制到相应的位置上,以便于接下来的轮次生成不同的密钥值memcpy(padding,seed,sizeof(seed));//将种子值复制到填充数组中,以便于接下来的轮次生成不同的随机数序列值for(round=0;round<ITERATIONS;round++){//进行加密轮次操作,每轮包括。

DES加密解密算法C语言代码实现

DES加密解密算法C语言代码实现

DES加密解密算法C语⾔代码实现代码:1 #include<stdio.h>2 #include<string.h>3 #include<stdlib.h>4/*------------------------5定义枚举型全局变量6------------------------*/7 typedef enum8 {9false = 0,10true = 111 } bool;1213// ⼗六轮⼦密钥14static bool SubKey[16][48]={0};1516/*---------------------*/17/*-------------------------------------------------------------18各种置换表19-------------------------------------------------------------*/20// IP置换表21const char IP_Table[64]={2258,50,42,34,26,18,10, 2,60,52,44,36,28,20,12, 4,2362,54,46,38,30,22,14, 6,64,56,48,40,32,24,16, 8,2457,49,41,33,25,17, 9, 1,59,51,43,35,27,19,11, 3,2561,53,45,37,29,21,13, 5,63,55,47,39,31,23,15, 726 };27// IP-1置换表28const char IPR_Table[64]={2940, 8,48,16,56,24,64,32,39, 7,47,15,55,23,63,31,3038, 6,46,14,54,22,62,30,37, 5,45,13,53,21,61,29,3136, 4,44,12,52,20,60,28,35, 3,43,11,51,19,59,27,3234, 2,42,10,50,18,58,26,33, 1,41, 9,49,17,57,2533 };3435// E扩展表36static char E_Table[48]={3732, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9,388, 9,10,11,12,13,12,13,14,15,16,17,3916,17,18,19,20,21,20,21,22,23,24,25,4024,25,26,27,28,29,28,29,30,31,32, 141 };42// PC1置换表43static char PC1_Table[56]={4457,49,41,33,25,17, 9, 1,58,50,42,34,26,18,4510, 2,59,51,43,35,27,19,11, 3,60,52,44,36,4663,55,47,39,31,23,15, 7,62,54,46,38,30,22,4714, 6,61,53,45,37,29,21,13, 5,28,20,12, 448 };4950// pc2表51static char PC2_Table[48]={5214,17,11,24, 1, 5, 3,28,15, 6,21,10,5323,19,12, 4,26, 8,16, 7,27,20,13, 2,5441,52,31,37,47,55,30,40,51,34,33,48,5544,49,39,56,34,53,46,42,50,36,29,3256 };57// 移位表58static char Move_Table[16]={591, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 160 };61// S盒62static char S_Box[8][4][16]={63//S16414, 4,13, 1, 2,15,11, 8, 3,10, 6,12, 5, 9, 0, 7,650,15, 7, 4,14, 2,13, 1,10, 6,12,11, 9, 5, 3, 8,664, 1,14, 8,13, 6, 2,11,15,12, 9, 7, 3,10, 5, 0,6715,12, 8, 2, 4, 9, 1, 7, 5,11, 3,14,10, 0, 6,13,68//S26915, 1, 8,14, 6,11, 3, 4, 9, 7, 2,13,12, 0, 5,10,703,13, 4, 7,15, 2, 8,14,12, 0, 1,10, 6, 9,11, 5,710,14, 7,11,10, 4,13, 1, 5, 8,12, 6, 9, 3, 2,15,7213, 8,10, 1, 3,15, 4, 2,11, 6, 7,12, 0, 5,14, 9,73//S37410, 0, 9,14, 6, 3,15, 5, 1,13,12, 7,11, 4, 2, 8,7513, 7, 0, 9, 3, 4, 6,10, 2, 8, 5,14,12,11,15, 1,7613, 6, 4, 9, 8,15, 3, 0,11, 1, 2,12, 5,10,14, 7,771,10,13, 0, 6, 9, 8, 7, 4,15,14, 3,11, 5, 2,12,78//S4797,13,14, 3, 0, 6, 9,10, 1, 2, 8, 5,11,12, 4,15,8013, 8,11, 5, 6,15, 0, 3, 4, 7, 2,12, 1,10,14, 9,8110, 6, 9, 0,12,11, 7,13,15, 1, 3,14, 5, 2, 8, 4,823,15, 0, 6,10, 1,13, 8, 9, 4, 5,11,12, 7, 2,14,83//S5842,12, 4, 1, 7,10,11, 6, 8, 5, 3,15,13, 0,14, 9,8514,11, 2,12, 4, 7,13, 1, 5, 0,15,10, 3, 9, 8, 6,864, 2, 1,11,10,13, 7, 8,15, 9,12, 5, 6, 3, 0,14,8711, 8,12, 7, 1,14, 2,13, 6,15, 0, 9,10, 4, 5, 3,88//S68912, 1,10,15, 9, 2, 6, 8, 0,13, 3, 4,14, 7, 5,11,9010,15, 4, 2, 7,12, 0, 5, 6, 1,13,14, 0,11, 3, 8,919,14,15, 5, 2, 8,12, 3, 7, 0, 4,10, 1,13,11, 6,924, 3, 2,12, 9, 5,15,10,11,14, 1, 7, 6, 0, 8,13,93//S7944,11, 2,14,15, 0, 8,13, 3,12, 9, 7, 5,10, 6, 1,9513, 0,11, 7, 4, 0, 1,10,14, 3, 5,12, 2,15, 8, 6,961, 4,11,13,12, 3, 7,14,10,15, 6, 8, 0, 5, 9, 2,976,11,13, 8, 1, 4,10, 7, 9, 5, 0,15,14, 2, 3,12,98//S89913, 2, 8, 4, 6,15,11, 1,10, 9, 3,14, 5, 0,12, 7,1001,15,13, 8,10, 3, 7, 4,12, 5, 6,11, 0,14, 9, 2,1017,11, 4, 1, 9,12,14, 2, 0, 6,10,13,15, 3, 5, 8,1022, 1,14, 7, 4,10, 8,13,15,12, 9, 0, 3, 5, 6,11103 };104//P置换表105static char P_Table[32]={10616, 7,20,21,29,12,28,17, 1,15,23,26, 5,18,31,10,1072, 8,24,14,32,27, 3, 9,19,13,30, 6,22,11, 4,25108 };109/*-------------------------------------------------------------------*/110111/*-----------------------------⾃定义函数-----------------------------*/112void SetKey(char My_key[8]); //⽣成16轮的⼦密钥;113void ByteToBit(bool * Data_out,char * Data_in,int Num); //字节转换成位;114void Change_bit(bool * Data_out,int Num);//⼆进制的位置进⾏转换;115void BitToByte(char My_message[8],bool * Message_in,int Num); //位转换成字节;116void TableReplace(bool *Data_out,bool *Data_in,const char *Table,int Num); //各种表的置换算法;117void Bitcopy(bool * Data_out,bool * Data_in,int Num); //⼆进制数组的拷贝118void Loop_bit(bool * Data_out,int movstep,int len); //左移位;119void Run_Des(char My_message[8],char HexMssage[16]);//des的轮加密算法120void Xor(bool * Message_out, bool * Message_in,int Num); //执⾏异或121void S_change(bool * Data_out, bool * Data_in); // S盒变换;122void HexToBit(bool * Data_out,char * Data_in,int Num); // ⼗六进制转⼆进制123void BitToHex(char * Data_out,bool * Data_in,int Num); //⼆进制转换成⼗六进制;124void Run_desDes(char My_message[8],char HexMessage[16]);// DES轮解密算法;125126/*--------------------------*/127128/*--------------------------主函数----------------------------------*/129int main()130 {131int i=0,j;132char My_key[8]={0}; //记录加密密钥;133char You_key[8]={0}; //解密密钥134char My_message[8]={0}; //明⽂135char Message_hex[16]={0};//16进制的密⽂136 printf("请输⼊你要加密的内容(8 Byte):\n");137 gets(My_message);138 printf("请输⼊你的加密密钥:\n");139 gets(My_key);140 i=strlen(My_key);141while(i!=8)142 {143 printf("请输⼊加密密钥(8 Byte)\n");144 gets(My_key);145 i=0;146 i=strlen(My_key);147 }148 SetKey(My_key); //⽣成16轮的加密⼦密钥;149 Run_Des(My_message,Message_hex); //des的轮加密过程150 printf("经过加密的密⽂为:\n");151for(i=0;i<16;i++)152 {153 printf("%c ",Message_hex[i]);154 }155 printf("\n");156 printf("请输⼊你的解密密钥(8 Byte):\n");157 gets(You_key);158 i=strlen(You_key);159while(i!=8)160 {161 printf("请输⼊解密密钥(8 Byte)\n");162 gets(You_key);164 i=strlen(You_key);165 }166 SetKey(You_key); //⽣成16轮的解密⼦密钥;167 Run_desDes(My_message,Message_hex);//解密;168 printf("解密结果为:\n");169for(i=0;i<8;i++)170 {171 printf("%c ",My_message[i]);172 }173 printf("\n");174return0;175 }176177/*--------------------具体函数定义----------------------*/178void Bitcopy(bool * Data_out, bool * Data_in,int Num) //⼆进制数组拷贝179 {180int i=0;181for(i=0;i<Num;i++)182 {183 Data_out[i]=Data_in[i];184 }185186 }187void Change_bit(bool * Data_out,int Num) //⼆进制的位置进⾏转换;188 {189int i,j;190static bool Temp[8]={0};191for(i=0;i<Num/8;i++)192 {193 Bitcopy(Temp,Data_out,Num/8);194for(j=0;j<Num/8;j++)195 {196 Data_out[j]=Temp[Num/8-1-j];197 }198 Data_out+=Num/8;199 }200 }201void ByteToBit( bool * Data_out,char * Data_in,int Num) //字节转位202 {203int i,j;204for(i=0;i<Num;i++)205 {206 Data_out[i]=(Data_in[i/8]>>(i%8))&0x01;207 }208//Change_bit(Data_out,Num);209 }210void BitToHex(char * Data_out, bool * Data_in,int Num) //⼆进制转⼗六进制211 {212int i;213for(i=0;i<Num/4;i++)214 {215 Data_out[i]=0;216 }217for(i=0;i<Num/4;i++)218 {219 Data_out[i]=Data_in[4*i]+Data_in[4*i+1]*2+Data_in[4*i+2]*4+Data_in[4*i+3]*8; 220if(Data_out[i]%16>9)221 {222 Data_out[i]=Data_out[i]%16+'7';223 }224else225 Data_out[i]=Data_out[i]%16+'0';226 }227 }228void HexToBit(bool * Data_out,char * Data_in,int Num) //⼗六进制转⼆进制229 {230int i;231for(i=0;i<Num;i++)232 {233if(Data_in[i/4]<='9')234 {235 Data_out[i]=((Data_in[i/4]-'0')>>(i%4))&0x01;236 }237else238 {239 Data_out[i]=((Data_in[i/4]-'7')>>(i%4))&0x01;240 }241 }242 }243void BitToByte(char My_message[8],bool * Message_in,int Num) //位转换成字节244 {245int i=0;246for(i=0;i<(Num/8);i++)248 My_message[i]=0;249 }250for(i=0;i<Num;i++)251 {252 My_message[i/8]|=Message_in[i]<<(i%8);253 }254 }255void TableReplace( bool *Data_out, bool * Data_in,const char *Table ,int Num) // 置换算法256 {257int i=0;258static bool Temp[256]={0};259for(i=0;i<Num;i++)260 {261 Temp[i]=Data_in[Table[i]-1];262 }263 Bitcopy(Data_out,Temp,Num);264 }265void Loop_bit(bool * Data_out,int movstep,int len)266 {267static bool Temp[256]={0};268 Bitcopy(Temp,Data_out,movstep);269 Bitcopy(Data_out,Data_out+movstep,len-movstep);270 Bitcopy(Data_out+len-movstep,Temp,movstep);271/*Temp=Data_out;272 Temp[movstep]='\0';273 Data_out=Data_out+movstep;274 Data_out+(len-movstep)=Temp;*/275 }276void Xor(bool * Message_out,bool * Message_in,int Num)//执⾏异或277 {278int i;279for(i=0;i<Num;i++)280 {281 Message_out[i]=Message_out[i]^Message_in[i];282 }283 }284void SetKey(char My_key[8])285 {286int i,j;287static bool Key_bit[64]={0}; //Key的⼆进制缓存;288static bool *Key_bit_L,*Key_bit_R;289 Key_bit_L=&Key_bit[0]; //key的左边28位;290 Key_bit_R=&Key_bit[28]; //key的右边28位;291 ByteToBit(Key_bit,My_key,64);292/* Change_bit(Key_bit,64) ;//⼆进制的位置进⾏转换;293 for(i=0;i<64;i++)294 {295 printf("%d ",Key_bit[i]);296 }297 printf("\n");298 printf("\n");*/299 TableReplace(Key_bit,Key_bit,PC1_Table,56);//pc-1 置换300for(i=0;i<16;i++)301 {302 Loop_bit(Key_bit_L,Move_Table[i],28);303 Loop_bit(Key_bit_R,Move_Table[i],28);304 TableReplace(SubKey[i],Key_bit,PC2_Table,48);//pc-2置换305 }306 }307void S_change(bool * Data_out, bool * Data_in) //S盒变换308 {309int i;310int r=0,c=0;//S盒的⾏和列;311for(i=0;i<8;i++,Data_in=Data_in+6,Data_out=Data_out+4)312 {313 r=Data_in[0]*2+Data_in[5]*1;314 c=Data_in[1]*8+Data_in[2]*4+Data_in[3]*2+Data_in[4]*1;315 ByteToBit(Data_out,&S_Box[i][r][c],4);316 }317 }318void F_change(bool Data_out[32],bool Data_in[48]) // f函数;319 {320int i;321static bool Message_E[48]={0}; //存放E置换的结果;322 TableReplace(Message_E,Data_out,E_Table,48);//E表置换323 Xor(Message_E,Data_in,48);324 S_change(Data_out,Message_E); // S盒变换325 TableReplace(Data_out,Data_out,P_Table,32); //P置换326 }327void Run_Des(char My_message[8],char HexMssage[16])//des轮加密算法;328 {329int i;330static bool Message_bit[64]={0};331static bool *Message_bit_L=&Message_bit[0],*Message_bit_R=&Message_bit[32]; 332static bool Temp[32]={0};333 ByteToBit(Message_bit,My_message,64);334/*Change_bit(Message_bit,64) ;//⼆进制的位置进⾏转换;335 for(i=0;i<64;i++)336 {337 printf("%d ",Message_bit[i]);338 }339 printf("\n");340 printf("\n");*/341 TableReplace(Message_bit,Message_bit,IP_Table,64);342for(i=0;i<16;i++)343 {344 Bitcopy(Temp,Message_bit_R,32);345 F_change(Message_bit_R,SubKey[i]);346 Xor(Message_bit_R,Message_bit_L,32);347 Bitcopy(Message_bit_L,Temp,32);348 }349 TableReplace(Message_bit,Message_bit,IPR_Table,64);350 BitToHex(HexMssage,Message_bit,64);//⼆进制转换成⼗六进制;351 }352void Run_desDes(char My_message[8],char HexMessage[16])// DES轮解密算法;353 {354int i=0;355static bool Message_bit[64]={0};356static bool * Message_bit_L=&Message_bit[0], * Message_bit_R=&Message_bit[32]; 357static bool Temp[32]={0};358 HexToBit(Message_bit,HexMessage,64);359 TableReplace(Message_bit,Message_bit,IP_Table,64);360for(i=15;i>=0;i--)361 {362 Bitcopy(Temp,Message_bit_L,32);363 F_change(Message_bit_L,SubKey[i]);364 Xor(Message_bit_L,Message_bit_R,32);365 Bitcopy(Message_bit_R,Temp,32);366 }367 TableReplace(Message_bit,Message_bit,IPR_Table,64);368 BitToByte(My_message,Message_bit,64);369 }。

DES加密原理学习,C#代码演示示例——加密与解密(一)

DES加密原理学习,C#代码演示示例——加密与解密(一)

DES加密原理学习,C#代码演⽰⽰例——加密与解密(⼀)(本⽰例仿照DES的加解密原理,使⽤C#编码,仅提供学习参考)⼀:定义⼀个静态类DesEntry,在其中实现⼀个静态⽅法,其⼤体流程框架如下1输⼊64位⼀组的明⽂,记为group2初始置换3,for i=0 to 15 {//设Lp,Rp分别为前⼀轮的左边32位与右32位,Lc,Rc同理为当前轮次与Lp,Rp相应的值3.1,Lc=Rp:将右32位换到左边,Rp代表前⼀轮的右边32位3.2,Rc=Lp^f(Rp,Kc):求取本轮右边32位,f为转换函数3.3,将Rp扩展置换成48位的新值并与Kc对合 3.4将上⼀项获得的新值以<b1,b2,b3,b4,b5,b6>形式分成8组,取b1b6构成的2位⼆进制数值,b2b3b4b5构成的4位⼆进制数值分别作为从S盒中的⾏和列索引, 从S盒中置换出相应的值(S[分组索引][⾏索引][列索引]),得到新的32位值3.5,再次将新值使⽤⼀个特定的置换函数置换成新的值3.6,将新值与Lp对合成新值3.7 串接LcRc,返回 }4,初始置换逆向5,输出加密解密采⽤相同算法代码如下:using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace JoeDES{public static class DESEntry64{#region加密//初始置换数组(64位),简称IP盒static int[] IP = new int[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};//初始置换逆变换数组,简称IP_1盒static int[] IP_1 = new int[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};//S盒(特定)static int[][][] S = new int[8][][];static DESEntry64(){S[0] = new int[4][];S[1] = new int[4][];S[2] = new int[4][];S[3] = new int[4][];S[4] = new int[4][];S[5] = new int[4][];S[6] = new int[4][];S[7] = new int[4][];S[0][0] = new int[] { 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, };S[0][1] = new int[] { 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, };S[0][2] = new int[] { 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, };S[0][3] = new int[] { 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13, };S[1][0] = new int[] { 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, };S[1][1] = new int[] { 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, };S[1][2] = new int[] { 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, };S[1][3] = new int[] { 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9, };S[2][0] = new int[] { 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, };S[2][1] = new int[] { 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 13, 11, 15, 1, };S[2][2] = new int[] { 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, };S[2][3] = new int[] { 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12, };S[3][0] = new int[] { 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, };S[3][1] = new int[] { 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, };S[3][2] = new int[] { 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, };S[3][3] = new int[] { 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14, };S[4][0] = new int[] { 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, };S[4][1] = new int[] { 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, };S[4][2] = new int[] { 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, };S[4][3] = new int[] { 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3, };S[5][0] = new int[] { 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, };S[5][1] = new int[] { 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, };S[5][2] = new int[] { 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, };S[5][3] = new int[] { 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13, };S[6][0] = new int[] { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, };S[6][1] = new int[] { 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, };S[6][2] = new int[] { 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, };S[6][3] = new int[] { 6, 11, 12, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12, };S[7][0] = new int[] { 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, };S[7][1] = new int[] { 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, };S[7][2] = new int[] { 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, };S[7][3] = new int[] { 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11, };}///<summary>///加密64位明⽂///</summary>///<param name="plainText6"></param>///<returns></returns>public static UInt64 Entry(UInt64 plainText64, UInt64 Key){return EntryAndDecrySharedMethod(plainText64, Key, true); ;}private static UInt64 InitialPlace(UInt64 plainText64){return IPlace(plainText64, IP);}private static UInt64 InitialReversePlace(UInt64 plainText64){return IPlace(plainText64, IP_1);}///<summary>/// DES初始换置与逆置换///</summary>///<param name="plainText64">等价于UInt64⼆进制形式的明⽂输⼊</param>///<param name="placeArray">等价于IP盒或IP_1盒的数组</param>///<returns></returns>private static UInt64 IPlace(UInt64 plainText64, int[] placeArray){UInt64 result = 0;//缓存结果//将输⼊参数的每个字节转化为⼆进制字符串形式,以⽅便对每个位进⾏位置变动//string operatorTempSb = data.ConvertToBitsString();//⽤于进⾏位置互换的辅助变量 UInt64 tempData = plainText64;//按照初始置换数组置换明⽂中的每⼀位⼆进制并输出到结果中for (int i = 0; i < 64; i++){tempData = plainText64 >> (64 - placeArray[i]);tempData = (tempData << 63);//tempData = tempData >> i;result = result ^ tempData;//result = Convert.ToInt64(operatorTempSb, 2);}return result;}//分组扩展///<summary>///扩展分组右32位到48位///</summary>///<param name="rightOfGroup32">包含分组右32位信息的输⼊(变量的低32位)</param>///<returns>返回被扩展的信息(值的低48位部分)</returns>///<remarks>E扩展,将32位⼆进制符号分为8组,每组头和尾部分别新增⼀个⼆进制位,前部为前⼀个索引对应的符号,尾部///为后⼀个索引对应的符号,其中第⼀组的前部为原来32位数的第32位,最后⼀组的尾部添加原32位符号的第⼀位符号。

des加密算法的实现及应用

des加密算法的实现及应用

DES加密算法的实现及应用学生姓名:梁帅指导老师:熊兵摘要随着信息与通信技术的迅猛发展和广泛应用,人们通过互联网进行信息交流,难免涉及到密码保护问题,这就需要使用DES加密技术来对数据进行加密保护。

本课程设计介绍了DES加密的基本原理以及简单的实现方法。

本课程设计基于C语言,采用DES算法技术,设计了DES加密程序,实现了DES加密解密功能。

经测试,程序能正常运行,实现了设计目标。

关键词DES加密,C语言,信息交流1 引言1.1本文主要内容DES是一个分组密码算法,使用64位密钥(除去8位奇偶校验,实际密钥长度为56位)对64比特的数据分组(二进制数据)加密,产生64位密文数据。

DES是一个对称密码体制,加密和解密使用同意密钥,解密和加密使用同一算法(这样,在硬件与软件设计时有利于加密单元的重用)。

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的加密过程:第一阶段:初始置换IP。

在第一轮迭代之前,需要加密的64位明文首先通过初始置换IP 的作用,对输入分组实施置换。

C语言加密与解密常用的加密算法和协议

C语言加密与解密常用的加密算法和协议

C语言加密与解密常用的加密算法和协议在计算机网络和信息安全领域,加密是一种广泛应用的技术,可以保护敏感数据的机密性和完整性。

C语言作为一种广泛使用的编程语言,提供了丰富的加密算法和协议的库函数,本文将介绍一些常用的加密算法和协议。

一、对称加密算法对称加密算法是指加密和解密使用相同密钥的算法,它的运算速度较快,适用于加密大量数据。

以下是几个常用的对称加密算法:1. DES(Data Encryption Standard)DES是一种基于对称密钥的加密算法,使用56位密钥进行加密和解密。

DES算法已经被证明在保护数据的机密性方面是有效的,但由于其较短的密钥长度,现在已经逐渐被更安全的算法取代。

2. AES(Advanced Encryption Standard)AES是一种高级加密标准算法,使用128、192或256位密钥进行加密和解密。

AES算法被广泛应用于各种领域,包括数据传输、硬盘加密和无线网络安全等。

它的安全性和性能都得到了广泛认可。

3. RC4(Rivest Cipher 4)RC4是一种流密码算法,它能够根据密钥流生成伪随机的密钥序列,并将明文与密钥序列进行异或操作,从而实现加密和解密功能。

尽管RC4算法在过去被广泛使用,但由于其存在一些安全漏洞,现在已经不推荐使用。

二、非对称加密算法非对称加密算法是指加密和解密使用不同密钥的算法,它能够提供更高的安全性,但性能较对称加密算法要低。

以下是几个常用的非对称加密算法:1. RSA(Rivest-Shamir-Adleman)RSA是一种基于大数因子分解的算法,广泛应用于数字签名、密钥交换和数据加密等领域。

它的安全性基于大数分解问题的困难性,目前被认为是非常安全的加密算法。

2. ECC(Elliptic Curve Cryptography)ECC是一种基于椭圆曲线的加密算法,它通过找到椭圆曲线上的一个点来生成公钥和私钥。

相较于RSA算法,ECC算法在提供相同安全性的情况下使用更短的密钥长度,从而提高了加密和解密的效率。

C#加密解密(DES,AES,Base64,md5,SHA256,RSA,RC4)

C#加密解密(DES,AES,Base64,md5,SHA256,RSA,RC4)

C#加密解密(DES,AES,Base64,md5,SHA256,RSA,RC4)⼀:异或^简单加解密(数字类型)1:原理:异或⽤于⽐较两个⼆进制数的相应位,在执⾏按位"异或"运算时,如果两个⼆进制数的相应位都为1或者都为0,则返回0;如果两个⼆进制数的相应位其中⼀个为1另⼀个为0,则返回1.//对数字加密int P_int_Num, P_int_Key;//定义两个值类型变量string Encryptstr = (P_int_Num ^ P_int_Key).ToString();//加密数值//对数字解密int P_int_Key, P_int_Encrypt;//定义两个值类型变量string Encryptstr =(P_int_Encrypt ^ P_int_Key).ToString();//解密数值⼆:加密解密类public class JiaMiJieMi{#region DES对称加密解密///<summary>加密字符串///</summary>///<param name="strText">需被加密的字符串</param>///<param name="strEncrKey">密钥</param>///<returns></returns>public static string DesEncrypt(string strText, string strEncrKey){try{byte[] byKey = null;byte[] IV = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };byKey = Encoding.UTF8.GetBytes(strEncrKey.Substring(0, 8));DESCryptoServiceProvider des = new DESCryptoServiceProvider();byte[] inputByteArray = Encoding.UTF8.GetBytes(strText);MemoryStream ms = new MemoryStream();CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(byKey, IV), CryptoStreamMode.Write);cs.Write(inputByteArray, 0, inputByteArray.Length);cs.FlushFinalBlock();return Convert.ToBase64String(ms.ToArray());}catch{return"";}}///<summary>解密字符串///</summary>///<param name="strText">需被解密的字符串</param>///<param name="sDecrKey">密钥</param>///<returns></returns>public static string DesDecrypt(string strText, string sDecrKey){try{byte[] byKey = null;byte[] IV = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };byte[] inputByteArray = new Byte[strText.Length];byKey = Encoding.UTF8.GetBytes(sDecrKey.Substring(0, 8));DESCryptoServiceProvider des = new DESCryptoServiceProvider();inputByteArray = Convert.FromBase64String(strText);MemoryStream ms = new MemoryStream();CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(byKey, IV), CryptoStreamMode.Write);cs.Write(inputByteArray, 0, inputByteArray.Length);cs.FlushFinalBlock();Encoding encoding = new UTF8Encoding();return encoding.GetString(ms.ToArray());}catchreturn null;}}///<summary>加密⽂件//////</summary>///<param name="m_InFilePath">原路径</param>///<param name="m_OutFilePath">加密后的⽂件路径</param>///<param name="strEncrKey">密钥</param>public static void DesEncryptFile(string m_InFilePath, string m_OutFilePath, string strEncrKey){try{byte[] byKey = null;byte[] IV = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };byKey = Encoding.UTF8.GetBytes(strEncrKey.Substring(0, 8));FileStream fin = new FileStream(m_InFilePath, FileMode.Open, FileAccess.Read);FileStream fout = new FileStream(m_OutFilePath, FileMode.OpenOrCreate, FileAccess.Write);fout.SetLength(0);//Create variables to help with read and write.byte[] bin = new byte[100]; //This is intermediate storage for the encryption.long rdlen = 0; //This is the total number of bytes written.long totlen = fin.Length; //This is the total length of the input file.int len; //This is the number of bytes to be written at a time.DES des = new DESCryptoServiceProvider();CryptoStream encStream = new CryptoStream(fout, des.CreateEncryptor(byKey, IV), CryptoStreamMode.Write);//Read from the input file, then encrypt and write to the output file.while (rdlen < totlen){len = fin.Read(bin, 0, 100);encStream.Write(bin, 0, len);rdlen = rdlen + len;}encStream.Close();fout.Close();fin.Close();}catch{}}///<summary>解密⽂件//////</summary>///<param name="m_InFilePath">被解密路径</param>///<param name="m_OutFilePath">解密后的路径</param>///<param name="sDecrKey">密钥</param>public static void DesDecryptFile(string m_InFilePath, string m_OutFilePath, string sDecrKey){try{byte[] byKey = null;byte[] IV = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };byKey = Encoding.UTF8.GetBytes(sDecrKey.Substring(0, 8));FileStream fin = new FileStream(m_InFilePath, FileMode.Open, FileAccess.Read);FileStream fout = new FileStream(m_OutFilePath, FileMode.OpenOrCreate, FileAccess.Write);fout.SetLength(0);//Create variables to help with read and write.byte[] bin = new byte[100]; //This is intermediate storage for the encryption.long rdlen = 0; //This is the total number of bytes written.long totlen = fin.Length; //This is the total length of the input file.int len; //This is the number of bytes to be written at a time.DES des = new DESCryptoServiceProvider();CryptoStream encStream = new CryptoStream(fout, des.CreateDecryptor(byKey, IV), CryptoStreamMode.Write);//Read from the input file, then encrypt and write to the output file.while (rdlen < totlen){len = fin.Read(bin, 0, 100);encStream.Write(bin, 0, len);rdlen = rdlen + len;}encStream.Close();fout.Close();fin.Close();catch{}}#endregion#region对称加密算法AES RijndaelManaged加密解密private static readonly string Default_AES_Key = "@#kim123";private static byte[] Keys = { 0x41, 0x72, 0x65, 0x79, 0x6F, 0x75, 0x6D, 0x79,0x53,0x6E, 0x6F, 0x77, 0x6D, 0x61, 0x6E, 0x3F };public static string AES_Encrypt(string encryptString){return AES_Encrypt(encryptString, Default_AES_Key);}public static string AES_Decrypt(string decryptString){return AES_Decrypt(decryptString, Default_AES_Key);}///<summary>对称加密算法AES RijndaelManaged加密(RijndaelManaged(AES)算法是块式加密算法) //////</summary>///<param name="encryptString">待加密字符串</param>///<param name="encryptKey">加密密钥,须半⾓字符</param>///<returns>加密结果字符串</returns>public static string AES_Encrypt(string encryptString, string encryptKey){encryptKey = GetSubString(encryptKey, 32, "");encryptKey = encryptKey.PadRight(32, '');RijndaelManaged rijndaelProvider = new RijndaelManaged();rijndaelProvider.Key = Encoding.UTF8.GetBytes(encryptKey.Substring(0, 32));rijndaelProvider.IV = Keys;ICryptoTransform rijndaelEncrypt = rijndaelProvider.CreateEncryptor();byte[] inputData = Encoding.UTF8.GetBytes(encryptString);byte[] encryptedData = rijndaelEncrypt.TransformFinalBlock(inputData, 0, inputData.Length);return Convert.ToBase64String(encryptedData);}///<summary>对称加密算法AES RijndaelManaged解密字符串//////</summary>///<param name="decryptString">待解密的字符串</param>///<param name="decryptKey">解密密钥,和加密密钥相同</param>///<returns>解密成功返回解密后的字符串,失败返回空</returns>public static string AES_Decrypt(string decryptString, string decryptKey){try{decryptKey = GetSubString(decryptKey, 32, "");decryptKey = decryptKey.PadRight(32, '');RijndaelManaged rijndaelProvider = new RijndaelManaged();rijndaelProvider.Key = Encoding.UTF8.GetBytes(decryptKey);rijndaelProvider.IV = Keys;ICryptoTransform rijndaelDecrypt = rijndaelProvider.CreateDecryptor();byte[] inputData = Convert.FromBase64String(decryptString);byte[] decryptedData = rijndaelDecrypt.TransformFinalBlock(inputData, 0, inputData.Length);return Encoding.UTF8.GetString(decryptedData);}catch{return string.Empty;}}///<summary>///按字节长度(按字节,⼀个汉字为2个字节)取得某字符串的⼀部分///</summary>///<param name="sourceString">源字符串</param>///<param name="length">所取字符串字节长度</param>///<param name="tailString">附加字符串(当字符串不够长时,尾部所添加的字符串,⼀般为"...")</param> ///<returns>某字符串的⼀部分</returns>private static string GetSubString(string sourceString, int length, string tailString){return GetSubString(sourceString, 0, length, tailString);}///<summary>///按字节长度(按字节,⼀个汉字为2个字节)取得某字符串的⼀部分///</summary>///<param name="sourceString">源字符串</param>///<param name="startIndex">索引位置,以0开始</param>///<param name="length">所取字符串字节长度</param>///<param name="tailString">附加字符串(当字符串不够长时,尾部所添加的字符串,⼀般为"...")</param>///<returns>某字符串的⼀部分</returns>private static string GetSubString(string sourceString, int startIndex, int length, string tailString){string myResult = sourceString;//当是⽇⽂或韩⽂时(注:中⽂的范围:\u4e00 - \u9fa5, ⽇⽂在\u0800 - \u4e00, 韩⽂为\xAC00-\xD7A3)if (System.Text.RegularExpressions.Regex.IsMatch(sourceString, "[\u0800-\u4e00]+") ||System.Text.RegularExpressions.Regex.IsMatch(sourceString, "[\xAC00-\xD7A3]+")){//当截取的起始位置超出字段串长度时if (startIndex >= sourceString.Length){return string.Empty;}else{return sourceString.Substring(startIndex,((length + startIndex) > sourceString.Length) ? (sourceString.Length - startIndex) : length); }}//中⽂字符,如"中国⼈民abcd123"if (length <= 0){return string.Empty;}byte[] bytesSource = Encoding.Default.GetBytes(sourceString);//当字符串长度⼤于起始位置if (bytesSource.Length > startIndex){int endIndex = bytesSource.Length;//当要截取的长度在字符串的有效长度范围内if (bytesSource.Length > (startIndex + length)){endIndex = length + startIndex;}else{ //当不在有效范围内时,只取到字符串的结尾length = bytesSource.Length - startIndex;tailString = "";}int[] anResultFlag = new int[length];int nFlag = 0;//字节⼤于127为双字节字符for (int i = startIndex; i < endIndex; i++){if (bytesSource[i] > 127){nFlag++;if (nFlag == 3){nFlag = 1;}}else{nFlag = 0;}anResultFlag[i] = nFlag;}//最后⼀个字节为双字节字符的⼀半if ((bytesSource[endIndex - 1] > 127) && (anResultFlag[length - 1] == 1)){length = length + 1;}byte[] bsResult = new byte[length];Array.Copy(bytesSource, startIndex, bsResult, 0, length);myResult = Encoding.Default.GetString(bsResult);myResult = myResult + tailString;return myResult;}return string.Empty;}///<summary>///加密⽂件流///</summary>///<param name="fs"></param>///<returns></returns>public static CryptoStream AES_EncryptStrream(FileStream fs, string decryptKey){decryptKey = GetSubString(decryptKey, 32, "");decryptKey = decryptKey.PadRight(32, '');RijndaelManaged rijndaelProvider = new RijndaelManaged();rijndaelProvider.Key = Encoding.UTF8.GetBytes(decryptKey);rijndaelProvider.IV = Keys;ICryptoTransform encrypto = rijndaelProvider.CreateEncryptor();CryptoStream cytptostreamEncr = new CryptoStream(fs, encrypto, CryptoStreamMode.Write);return cytptostreamEncr;}///<summary>///解密⽂件流///</summary>///<param name="fs"></param>///<returns></returns>public static CryptoStream AES_DecryptStream(FileStream fs, string decryptKey){decryptKey = GetSubString(decryptKey, 32, "");decryptKey = decryptKey.PadRight(32, '');RijndaelManaged rijndaelProvider = new RijndaelManaged();rijndaelProvider.Key = Encoding.UTF8.GetBytes(decryptKey);rijndaelProvider.IV = Keys;ICryptoTransform Decrypto = rijndaelProvider.CreateDecryptor();CryptoStream cytptostreamDecr = new CryptoStream(fs, Decrypto, CryptoStreamMode.Read);return cytptostreamDecr;}///<summary>///对指定⽂件加密///</summary>///<param name="InputFile"></param>///<param name="OutputFile"></param>///<returns></returns>public static bool AES_EncryptFile(string InputFile, string OutputFile){try{string decryptKey = "";FileStream fr = new FileStream(InputFile, FileMode.Open);FileStream fren = new FileStream(OutputFile, FileMode.Create);CryptoStream Enfr = AES_EncryptStrream(fren, decryptKey);byte[] bytearrayinput = new byte[fr.Length];fr.Read(bytearrayinput, 0, bytearrayinput.Length);Enfr.Write(bytearrayinput, 0, bytearrayinput.Length);Enfr.Close();fr.Close();fren.Close();}catch{//⽂件异常return false;}return true;}///<summary>///对指定的⽂件解压缩///</summary>///<param name="InputFile"></param>///<param name="OutputFile"></param>///<returns></returns>public static bool AES_DecryptFile(string InputFile, string OutputFile){try{string decryptKey = "";FileStream fr = new FileStream(InputFile, FileMode.Open);FileStream frde = new FileStream(OutputFile, FileMode.Create);CryptoStream Defr = AES_DecryptStream(fr, decryptKey);byte[] bytearrayoutput = new byte[1024];int m_count = 0;do{m_count = Defr.Read(bytearrayoutput, 0, bytearrayoutput.Length);frde.Write(bytearrayoutput, 0, m_count);if (m_count < bytearrayoutput.Length)break;} while (true);Defr.Close();fr.Close();frde.Close();}catch{//⽂件异常return false;}return true;}#endregion#region Base64加密解密///<summary>/// Base64是⼀種使⽤64基的位置計數法。

DES 加密解密算法的C完成 实验报告

DES 加密解密算法的C完成 实验报告
DES 密码实际上是 Lucifer 密码的进一步发展。它是一种采用传统加密方法的区组密 码。它的算法是对称的,既可用于加密又可用于解密。
美国国家标准局 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_加密解密算法的C++实现

DES_加密解密算法的C++实现
private: string plaintextFilePath_;/*明文文件路径*/ string ciphertextFilePath_;/*密文文件路径*/ string keyFilename_;/*密钥文件路径*/
string plaintext_;/*明文存储*/ string ciphertext_;/*密文存储*/ string key_;/*密钥存储*/
const unsigned int DES::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 };
算法的整体结构:有 16 个相同的处理过程,称为“回次”,并在首位各 有一次置换。在主处理回次前,数据块被分成两个 32 位的半块,并被分别 处理。图中的⊕符号代表异或操作。“F 函数”将数据半块与某个子密钥进行 处理。然后,一个 F 函数的输出与另一个半块异或之后,再与原本的半块 组合并交换顺序,进入下一个回次的处理。在最后一个回次完成时,两个 半块不必交换顺序 。
const unsigned int DES::PC_1_[56] = { /*注释的部分是对应 64 位带奇偶校验的*/ /*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*/ 50, 43, 36, 29, 22, 15, 8, 1, 51, 44, 37, 30, 23, 16, 9, 2, 52, 45, 38, 31, 24, 17, 10, 3, 53, 46, 39, 32, 56, 49, 42, 35, 28, 21, 14, 7, 55, 48, 41, 34, 27, 20, 13, 6, 54, 47, 40, 33, 26, 19, 12, 5, 25, 18, 11, 4 };

C语言实现DES加密解密算法

C语言实现DES加密解密算法

C语言实现DES加密解密算法
最近几十年里,DES(Data Encryption Standard)算法的发展起到
了极其重要的作用。

Des算法是一种基于分组密码的算法。

算法将64位
的明文数据块按位分组成8个字节,每一组以8位为单位转换成一个64
位的密文数据块,采用16轮的分组加密,每次密码变化,保证加密强度。

本文详细介绍了DES算法的C语言实现,并分别介绍了加解密算法的实现
步骤以及DES加解密测试过程。

一、DES算法C语言实现
1.函数原型
DES算法的实现包括加密和解密函数,函数原型如下:
unsigned char* DesEncrypt(unsigned char *src, unsigned char
*key); // DES加密函数
unsigned char* DesDecrypt(unsigned char *src, unsigned char
*key); // DES解密函数
输入参数src是指明文源数据,key是加解密密钥,输出参数为一个
指向加解密结果的字符串指针。

2.加解密算法
(1)DES加密算法
DES加密算法步骤如下:
(i)初始置换:将64位明文块做一次IP置换得到L0R0。

(ii)迭代轮换:对L0R0经过16次迭代轮换后,最终结果为
L16R16
(iii)逆置换:L16R16进行逆置换得到64位密文。

(2)DES解密算法
DES解密算法步骤和DES加密算法步骤是一样的,只是将置换步骤改为逆置换,将轮换步骤改为逆轮换即可。

三、DES加解密测试
1.程序测试
在C语言编写完DES加解密算法之后。

C语言实现数据加密算法

C语言实现数据加密算法

C语言实现数据加密算法数据加密是对敏感信息进行转换的过程,以保护数据的机密性和完整性。

C语言提供了强大的工具和库来实现各种加密算法,包括对称加密和非对称加密等。

对称加密算法是一种使用相同密钥加密和解密数据的方法。

其中最常见的算法是DES(Data Encryption Standard)和AES(Advanced Encryption Standard)。

下面是一个实现AES算法的示例代码:```c#include <stdio.h>#include <stdlib.h>#include <string.h>#include <openssl/aes.h>void encrypt_data(const unsigned char *data, size_t len, const unsigned char *key, unsigned char *encrypted_data) AES_KEY aes_key;AES_set_encrypt_key(key, 128, &aes_key);AES_encrypt(data, encrypted_data, &aes_key);void decrypt_data(const unsigned char *encrypted_data,size_t len, const unsigned char *key, unsigned char *data) AES_KEY aes_key;AES_set_decrypt_key(key, 128, &aes_key);AES_decrypt(encrypted_data, data, &aes_key);int maiunsigned char data[AES_BLOCK_SIZE] = "hello world!";size_t len = sizeof(data);unsigned char encrypted_data[AES_BLOCK_SIZE];encrypt_data(data, len, key, encrypted_data);unsigned char decrypted_data[AES_BLOCK_SIZE];decrypt_data(encrypted_data, len, key, decrypted_data);printf("Original Data: %s\n", data);printf("Encrypted Data: ");for (int i = 0; i < len; i++)printf("%02x ", encrypted_data[i]);}printf("\nDecrypted Data: %s\n", decrypted_data);return 0;```以上代码使用了OpenSSL库中的AES加密算法。

使用C#DES解密javaDES加密的字符串

使用C#DES解密javaDES加密的字符串

使⽤C#DES解密javaDES加密的字符串转⾃最近需要使⽤C#的DES解密⼯具类解密字符串,但是要解密的字符串是使⽤java进⾏DES加密的,去⽹上查了关于C#和java关于DES加密解密的资料,发现可以相互加密解密的时候,java进⾏DES加密⼀般都会写成如下:public static byte[] encrypt(String message, String key) throws Exception {Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("UTF-8"));SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");// 密钥SecretKey secretKey = keyFactory.generateSecret(desKeySpec);// 偏移量IvParameterSpec iv = new IvParameterSpec(key.getBytes("UTF-8"));cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);return cipher.doFinal(message.getBytes("UTF-8"));}因为初始化Cipher的时候设置了密钥和偏移量,所以C#的DESCryptoServiceProvider类可以很容易的进⾏解密。

C#解密代码如下:public static string Decode(string str, string key){try{DESCryptoServiceProvider provider = new DESCryptoServiceProvider();// 密钥provider.Key = Encoding.ASCII.GetBytes(key.Substring(0, 8));// 偏移量provider.IV = Encoding.ASCII.GetBytes(key.Substring(0, 8));byte[] buffer = new byte[str.Length / 2];for (int i = 0; i < (str.Length / 2); i++){int num2 = Convert.ToInt32(str.Substring(i * 2, 2), 0x10);buffer[i] = (byte)num2;}MemoryStream stream = new MemoryStream();CryptoStream stream2 = new CryptoStream(stream, provider.CreateDecryptor(),CryptoStreamMode.Write);stream2.Write(buffer, 0, buffer.Length);stream2.FlushFinalBlock();stream.Close();return Encoding.GetEncoding("GB2312").GetString(stream.ToArray());}catch (Exception) { return ""; }}现在的问题是java的DES加密不仅仅有上⾯⼀种写法,我需要解密的字符串是使⽤如下java代码进⾏加密的:public static byte[] encrypt(String message, String key) throws Exception {SecureRandom sr = new SecureRandom();Cipher cipher = Cipher.getInstance("DES");DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("UTF-8"));SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");SecretKey secretKey = keyFactory.generateSecret(desKeySpec);// 这⾥使⽤的是另⼀个init⽅法cipher.init(Cipher.ENCRYPT_MODE, secretKey, sr);return cipher.doFinal(message.getBytes("UTF-8"));}这样的话,java加密的偏移量没有设置,⽽且通过测试发现就算上⾯设置了偏移量,Cipher cipher = Cipher.getInstance("DES");和Cipher cipher =Cipher.getInstance("DES/CBC/PKCS5Padding"); 加密之后的结果也不⼀样,所以这样的话使⽤C#解密的时候就不知道相应的偏移量应该怎么设置,⿇烦各位⾼⼿指导⼀下,谢谢问题补充:DES加密解密结果⼀般要注意的地⽅:密钥、偏移量、块密码模式、填充模式java DES加密的时候:如果使⽤这种⽅式,Cipher cipher = Cipher.getInstance("DES"); 此时块密码模式⽤ECB模式,C#DES类默认模式是CBC模式,所以如果java使⽤上⾯的⽅式进⾏初始化的时候,使⽤C#解密的时候要记得设置Mode属性为ECB,另外,如果没有设置偏所以对于上⾯java的第2种DES加密⽅法,使⽤C#解密的时候只需要在解密之前加上provider.Mode = CipherMode.ECB;就可以了。

DES加密C语言实现源代码

DES加密C语言实现源代码

void *memcpy( void *dest, const void *src, unsigned char count ){// ASSERT((dest != NULL)&&(src != NULL));unsigned char *temp_dest = (unsigned char *)dest;unsigned char *temp_src = (unsigned char *)src;while(count--) // 不对是否存在重叠区域进行判断{*temp_dest++ = *temp_src++;}return dest;}unsigned char *memset(unsigned char *dst,unsigned char value,unsigned char count) {unsigned char *start = dst;while (count--)*dst++ = value;return(start);}// 初始置换表IPunsigned char IP_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};//逆初始置换表IP^-1unsigned char IP_1_Table[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}; //扩充置换表Eunsigned char E_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};//置换函数Punsigned char P_Table[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};//S盒unsigned char S[8][4][16] =// 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,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}}, //S3{{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}}, // S4{{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}}, //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}}};//置换选择1unsigned char PC_1[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};//置换选择2unsigned char PC_2[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,46,43,48,38,55,33,52,45,41,49,35,28,31};// 对左移次数的规定unsigned char MOVE_TIMES[16] = {1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1}; //字节转换成二进制unsigned char ByteToBit(unsigned char ch, unsigned char bit[8]) {unsigned char cnt;for(cnt = 0;cnt < 8; cnt++){*(bit+cnt) = (ch>>cnt)&1;}return 0;}// 二进制转换成字节unsigned char BitToByte(unsigned char bit[8],unsigned char *ch){unsigned char cnt;for(cnt = 0;cnt < 8; cnt++){*ch |= *(bit + cnt)<<cnt;}return 0;}// 将长度为8的字符串转为二进制位串unsigned char Char8ToBit64(unsigned char ch[8],unsigned char bit[64]){unsigned char cnt;for(cnt = 0; cnt < 8; cnt++){ByteToBit(*(ch+cnt),bit+(cnt<<3));}return 0;}// 将二进制位串转为长度为8的字符串unsigned char Bit64ToChar8(unsigned char bit[64],unsigned char ch[8]){unsigned char cnt;memset(ch,0,8);for(cnt = 0; cnt < 8; cnt++){BitToByte(bit+(cnt<<3),ch+cnt);}return 0;}// 密钥置换1unsigned char DES_PC1_Transform(unsigned char key[64], unsigned char tempbts[56]) {unsigned char cnt;for(cnt = 0; cnt < 56; cnt++){tempbts[cnt] = key[PC_1[cnt]];}return 0;}//密钥置换2unsigned char DES_PC2_Transform(unsigned char key[56], unsigned char tempbts[48]) {unsigned char cnt;for(cnt = 0; cnt < 48; cnt++){tempbts[cnt] = key[PC_2[cnt]];}return 0;}//循环左移unsigned char DES_ROL(unsigned char data[56], unsigned char time){unsigned char temp[56];//保存将要循环移动到右边的位memcpy(temp,data,time);memcpy(temp+time,data+28,time);//前28位移动memcpy(data,data+time,28-time);memcpy(data+28-time,temp,time);//后28位移动memcpy(data+28,data+28+time,28-time);memcpy(data+56-time,temp+time,time);return 0;}//IP置换unsigned char DES_IP_Transform(unsigned char data[64]){unsigned char cnt;unsigned char temp[64];for(cnt = 0; cnt < 64; cnt++){temp[cnt] = data[IP_Table[cnt]];}memcpy(data,temp,64);return 0;}// IP逆置换unsigned char DES_IP_1_Transform(unsigned char data[64]) {unsigned char cnt;unsigned char temp[64];for(cnt = 0; cnt < 64; cnt++){temp[cnt] = data[IP_1_Table[cnt]];}memcpy(data,temp,64);return 0;}//扩展置换unsigned char DES_E_Transform(unsigned char data[48]) {unsigned char cnt;unsigned char temp[48];for(cnt = 0; cnt < 48; cnt++){temp[cnt] = data[E_Table[cnt]];}memcpy(data,temp,48);return 0;}//P置换unsigned char DES_P_Transform(unsigned char data[32]) {unsigned char cnt;unsigned char temp[32];for(cnt = 0; cnt < 32; cnt++){temp[cnt] = data[P_Table[cnt]];}memcpy(data,temp,32);return 0;}// 异或unsigned char DES_XOR(unsigned char R[48], unsigned char L[48] ,unsigned char count) {unsigned char cnt;for(cnt = 0; cnt < count; cnt++){R[cnt] ^= L[cnt];}return 0;}// S盒置换unsigned char DES_SBOX(unsigned char data[48]){unsigned char cnt;unsigned char line,row,output;unsigned char cur1,cur2;for(cnt = 0; cnt < 8; cnt++){cur1 = cnt*6;cur2 = cnt<<2;// 计算在S盒中的行与列line = (data[cur1]<<1) + data[cur1+5];row = (data[cur1+1]<<3) + (data[cur1+2]<<2)+ (data[cur1+3]<<1) + data[cur1+4];output = S[cnt][line][row];// 化为2进制data[cur2] = (output&0X08)>>3;data[cur2+1] = (output&0X04)>>2;data[cur2+2] = (output&0X02)>>1;data[cur2+3] = output&0x01;}return 0;}//交换unsigned char DES_Swap(unsigned char left[32], unsigned char right[32]){unsigned char temp[32];memcpy(temp,left,32);memcpy(left,right,32);memcpy(right,temp,32);return 0;}//生成子密钥unsigned char DES_MakeSubKeys(unsigned char key[64],unsigned char subKeys[16][48]){unsigned char temp[56];unsigned char cnt;DES_PC1_Transform(key,temp);// PC1置换for(cnt = 0; cnt < 16; cnt++) //16轮跌代,产生16个子密钥{DES_ROL(temp,MOVE_TIMES[cnt]);// 循环左移DES_PC2_Transform(temp,subKeys[cnt]);//PC2置换,产生子密钥}return 0;}//加密单个分组unsigned char DES_EncryptBlock(unsigned char plainBlock[8], unsigned char subKeys[16][48], unsigned char cipherBlock[8]){unsigned char plainBits[64];unsigned char copyRight[48];unsigned char cnt;Char8ToBit64(plainBlock,plainBits);//初始置换(IP置换)DES_IP_Transform(plainBits);// 16轮迭代for(cnt = 0; cnt < 16; cnt++){memcpy(copyRight,plainBits+32,32);DES_E_Transform(copyRight); // 将右半部分进行扩展置换,从32位扩展到48位DES_XOR(copyRight,subKeys[cnt],48); // 将右半部分与子密钥进行异或操作DES_SBOX(copyRight); // 异或结果进入S盒,输出32位结果DES_P_Transform(copyRight); // P置换DES_XOR(plainBits,copyRight,32); //将明文左半部分与右半部分进行异或if(cnt != 15){DES_Swap(plainBits,plainBits+32);//最终完成左右部的交换}}DES_IP_1_Transform(plainBits); //逆初始置换(IP^1置换)Bit64ToChar8(plainBits,cipherBlock);return 0;}// 解密单个分组unsigned char DES_DecryptBlock(unsigned char cipherBlock[8], unsigned char subKeys[16][48],unsigned char plainBlock[8]){unsigned char cipherBits[64];unsigned char copyRight[48];short cnt;Char8ToBit64(cipherBlock,cipherBits);//初始置换(IP置换)DES_IP_Transform(cipherBits);// 16轮迭代for(cnt = 15; cnt >= 0; cnt--){memcpy(copyRight,cipherBits+32,32);//将右半部分进行扩展置换,从32位扩展到48位DES_E_Transform(copyRight);// 将右半部分与子密钥进行异或操作DES_XOR(copyRight,subKeys[cnt],48);//异或结果进入S盒,输出32位结果DES_SBOX(copyRight);// P置换DES_P_Transform(copyRight);//将明文左半部分与右半部分进行异或DES_XOR(cipherBits,copyRight,32);if(cnt != 0){// 最终完成左右部的交换DES_Swap(cipherBits,cipherBits+32);}}// 逆初始置换(IP^1置换)DES_IP_1_Transform(cipherBits);Bit64ToChar8(cipherBits,plainBlock);return 0;}//加密文件unsigned char DES_Encrypt(unsigned char *keyStr,unsigned char *plainFile,unsigned char *cipherFile){unsigned char keyBlock[8],bKey[64],subKeys[16][48];memcpy(keyBlock,keyStr,8); //设置密钥Char8ToBit64(keyBlock,bKey); //将密钥转换为二进制流DES_MakeSubKeys(bKey,subKeys); //生成子密钥DES_EncryptBlock(plainFile,subKeys,cipherFile);return 1;}//解密文件unsigned char DES_Decrypt(unsigned char *keyStr,unsigned char *cipherFile,unsigned char *plainFile){// unsigned char plainBlock[8],cipherBlock[8],unsigned char bKey[64],keyBlock[8],subKeys[16][48];memcpy(keyBlock,keyStr,8); //设置密钥Char8ToBit64(keyBlock,bKey); //将密钥转换为二进制流DES_MakeSubKeys(bKey,subKeys); //生成子密钥DES_DecryptBlock(cipherFile,subKeys,plainFile);return 1;}/****************************************************************************** ****************** 作者:win2kddk* 说明:3重DES是使用16字节密钥将8字节明文数据块进行3次DES加密和解密。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

#include<stdio.h>#include<stdlib.h>#include<string.h>void show1() //主界面{printf("\n\n\n\t\t*************** DES加密解密系统******************\n\n");printf("\t\t--------------------------------------------------\n");//printf("\t\t--------------------------------------------------\n");printf("\t\t**************************************************\n");printf("\t\t**\t\t\t\t\t\t**\n");printf("\t\t**\t\t\t\t\t\t**\n");printf("\t\t**\t\t\t1.加密\t\t\t**\n");printf("\t\t**\t\t\t\t\t\t**\n");printf("\t\t**\t\t\t2.解密\t\t\t**\n");printf("\t\t**\t\t\t\t\t\t**\n");printf("\t\t**\t\t\t3.退出\t\t\t**\n");printf("\t\t**\t\t\t\t\t\t**\n");printf("\t\t**\t\t\t\t\t\t**\n");printf("\t\t--------------------------------------------------\n");}void show2() //加密界面{printf("\n\n\n\t\t****************** DES加密**********************\n\n");printf("\t\t--------------------------------------------------\n");printf("\t\t**************************************************\n");printf("\t\t**\t\t\t\t\t\t**\n");printf("\t\t**\t请选择明文和密钥的输入方式:\t\t**\n");printf("\t\t**\t\t\t\t\t\t**\n");printf("\t\t**\t\t1.直接输入\t\t\t**\n");printf("\t\t**\t\t\t\t\t\t**\n");printf("\t\t**\t\t2.从文件读取\t\t\t**\n");printf("\t\t**\t\t\t\t\t\t**\n");printf("\t\t**\t\t3.退出\t\t\t\t**\n");printf("\t\t**\t\t\t\t\t\t**\n");printf("\t\t--------------------------------------------------\n");printf("\t\t\t选择:");}void reader(char str[30],char s[8]) //读取明文和密钥{FILE *fp;fp=fopen(str,"r");if(fp==NULL){printf("明文读取失败!\n");}else{fscanf(fp,"%s",s);}fclose(fp);}void To2Bin(char p[8],int b[64]) //将字节转换成二进制流{int i,k=0;for(i=0;i<8;i++){int j=0x80;for(;j;j>>=1){if(j&p[i]){b[k++]=1;}else{b[k++]=0;}}}}int IP_Table[64] = //初始置换(IP){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};int E_Table[] = { //扩展变换E31, 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_Box[8][4][16] = { //8个s盒{{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 IP_1_Table[64] = //逆初始置换IP^-1 {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};int P_Table[32] = //置换运算P{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};int PC_1[56] ={56,48,40,32,24,16,8, //密钥置换PC_10,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};int PC_2[48] = //密钥置换PC_2{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};void Replacement(int arry1[],int arry2[],int arry3[],int num) //置换函数(初始IP,逆初始IP,{int i,tmp;for(i=0;i<num;i++){tmp=arry2[i];arry3[i]=arry1[tmp];}}int move_times[16] = {1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1}; //对左移位的规定void lif_move(int arry1[],int arry2[],int n) //左移位实现函数{int i;for(i=0;i<28;i++){arry2[i]=arry1[(n+i)%28];}}int K[16][48]; //存放16轮子密钥int c[64]; //存放明文或密文int L[17][32],R[17][32]; //存放加密过程中左右部分void SubKey(int K0[64]) //子密钥产生函数{int i;int K1[56],K2[56];int C[17][28],D[17][28];Replacement(K0,PC_1,K1,56); //密钥置换PC_1for(i=0;i<28;i++) //将PC_1输出的56比特分为左右两部分{C[0][i]=K1[i];D[0][i]=K1[i+28];}i=0;while(i<16){int j;lif_move(C[i],C[i+1],move_times[i]);lif_move(D[i],D[i+1],move_times[i]);for(j=0;j<28;j++){K2[j]=C[i+1][j];K2[j+28]=D[i+1][j];}Replacement(K2,PC_2,K[i],48); //密钥置换PC_2i++;}/*printf("\n子密钥生成过程中,左边生成的值:");for(i=0;i<17;i++){int j;printf("\nC[%d]:",i);for(j=0;j<28;j++){if(j%7==0){printf(" ");}printf("%d",C[i][j]);}}printf("\n子密钥生成过程中,右边生成的值:");for(i=0;i<17;i++){int j;printf("\nD[%d]:",i);for(j=0;j<28;j++){if(j%7==0){printf(" ");}printf("%d",D[i][j]);}}*/}void S_compress(int arry[],int shc[]) //S盒压缩变换,其中数组shc存放经过s盒的结果{int h,l; //行,列int sha[8]; //存放经过s盒的十进制结果int i,j;int temp[4];for(i=0;i<8;i++) //s盒压缩变换{h=arry[(1+(i*6))-1]*2 + arry[(6+(i*6))-1];l =arry[(2+(i*6))-1]*8 + arry[(3+(i*6))-1]*4 + arry[(4+(i*6))-1]*2 + arry[(5+(i*6))-1];sha[i]=S_Box[i][h][l];}for(i=0;i<8;i++){for(j=3;j>=0;j--){sha[i]=sha[i]/2;}for(j=0;j<4;j++){shc[4*i+j]=temp[j];}}/*printf("\n第%d次s盒的输出:",m++);for(i=0;i<32;i++){if(i%8==0){printf(" ");}printf("%d",shc[i]);}*/}void To10(int a[], int b[],int n)//二进制转十进制{int i,j;int temp;int arry[16][4];for(i=0;i<n/4;i++){for(j=0;j<4;j++){arry[i][j]=a[4*i+j];}}for (i=0;i<n/4;i++){temp=arry[i][0]*8+arry[i][1]*4+arry[i][2]*2+arry[i][3]*1;/*for(j=3;j>=0;j--){if(arry[i][j]==1){t=1;for(k=0;k<3-j;k++){t=t*2;}}}*/b[i]=temp;}}void To102(int a[], int b[],int n)//二进制转十进制{int i,j;int temp;int arry[8][8];int t=1,k;for(i=0;i<n/8;i++){for(j=0;j<8;j++){arry[i][j]=a[8*i+j];}}for (i=0;i<n/8;i++){temp=0;for(j=7;j>=0;j--){if(arry[i][j]==1){t=1;for(k=0;k<7-j;k++){t=t*2;}temp+=t;}}b[i]=temp;}}void F_Function(int a[32],int b[32],int n) //F函数{int i;int tmp[48];int tep[32];Replacement(a,E_T able,tmp,48); //扩展变换E /*printf("\n第%d轮E盒扩展结果:",n);for(i=0;i<48;i++){if(i%8==0)printf(" ");printf("%d",tmp[i]);}*/for(i=0;i<48;i++) //与子密钥异或{tmp[i] ^= K[n][i];}/*printf("\n进入S盒的48比特:");for(i=0;i<48;i++){if(i%6==0){printf(" ");}printf("%d",tmp[i]);}*/S_compress(tmp,tep); //压缩变换SReplacement(tep,P_Table,b,32); //置换运算P/*printf("\n第%d次P置盒输出:",l++);for(i=0;i<32;i++){if(i%8==0)printf(" ");printf("%d",b[i]);}*//*printf("\nf[%d]的输出结果:",n);for(i=0;i<32;i++){if(i%8==0){printf(" ");}printf("%d",b[i]);}*/}void Encryption(int m0[64],int c1[64]){int i,k;int arry[32];int c0[64],m1[64];Replacement(m0,IP_Table,m1,64); //初始置换IP/*printf("\n初始置换:");for(i=0;i<64;i++){if(i%8==0)printf(" ");printf("%d",m1[i]);}*/for(i=0;i<32;i++){L[0][i]=m1[i];R[0][i]=m1[i+32];}k=1;while(k<17){F_Function(R[k-1],arry,k-1);for(i=0;i<32;i++){L[k][i]=R[k-1][i];R[k][i]=L[k-1][i]^arry[i];}k++;}for(i=0;i<32;i++){c0[i]=R[16][i];c0[i+32]=L[16][i];}Replacement(c0,IP_1_Table,c1,64); //逆初始置换}void changeKey(int a[16][48]){int i,j;int tmp[16][48];for(i=0;i<16;i++)for(j=0;j<48;j++){tmp[i][j]=a[i][j];}}for(i=0;i<16;i++){for(j=0;j<48;j++){K[i][j]=tmp[15-i][j];}}}void Decryption(int c1[],int m[]){int c0[64],t[64];int i,k;int arry[32];changeKey(K);/*printf("\n交换后的密钥:\n");for(i=0;i<16;i++){printf("\n");for(j=0;j<48;j++){if(j%8==0){printf(" ");}printf("%d",K[i][j]);}}*/Replacement(c1,IP_Table,c0,64); //初始IP for(i=0;i<32;i++){L[0][i]=c0[i];R[0][i]=c0[i+32];}k=1;while(k<17)F_Function(R[k-1],arry,k-1);for(i=0;i<32;i++){L[k][i]=R[k-1][i];R[k][i]=L[k-1][i]^arry[i];}k++;}for(i=0;i<32;i++){t[i]=R[16][i];t[i+32]=L[16][i];}Replacement(t,IP_1_T able,m,64); //逆初始置换}void print() //输出函数{int i;int a[12],b[12],d[3][16];int p[64],q[64];for(i=0;i<32;i++){p[i]=L[15][i];p[32+i]=R[15][i];q[i]=R[16][i];q[i+32]=L[16][i];}To10(K[14],a,48);To10(K[15],b,48);To10(c,d[0],64);To10(p,d[1],64);To10(q,d[2],64);printf("\n\t\t15轮密钥:");for(i=0;i<12;i++){printf("%x",a[i]);}printf("\t15轮结果:");for(i=0;i<16;i++){printf("%X",d[1][i]);printf("\n\t\t16轮密钥:");for(i=0;i<12;i++){printf("%X",b[i]);}printf("\t16轮结果:");for(i=0;i<16;i++){printf("%X",d[2][i]);}printf("\n\t\t最后结果:");for(i=0;i<16;i++){printf("%X",d[0][i]);}/*printf("\n最后结果二进制:");for(i=0;i<64;i++){printf("%d",c[i]);}*/}int main(){int num,i,t;char s1[8],s2[8];int m[64]; //m存放二进制明文/密文int d[64]; //存放二进制密钥int s[8];show1();printf("\t\tinput you choice:");while(1){scanf("%d",&num);switch(num){case 1:system("cls"); //调用清屏函数show2();{scanf("%d",&num);if(num==1){while(strlen(s1)!=8){printf("\t\t请输入明文(8):");scanf("%s",s1);}To2Bin(s1,m); //将明文转换成二进制流while(strlen(s2)!=8){printf("\t\t请输入密钥(8):");scanf("%s",s2);}To2Bin(s2,d); //将密钥转换成二进制/*printf("\n初始二进制明文:");for(i=0;i<64;i++){printf("%d",m[i]);}*//*printf("\n初始二进制密钥:");for(i=0;i<64;i++){printf("%d",d[i]);}*/SubKey(d);/*printf("\n16轮子密钥如下:");for(i=0;i<16;i++){printf("\nK[%d]:",i+1);for(j=0;j<48;j++){if(j%8==0)printf(" ");printf("%d",K[i][j]);}}*/Encryption(m,c);/*printf("\n16次迭代左结果:");for(i=0;i<17;i++){printf("\nL[%d]:",i);for(j=0;j<32;j++){if(j%8==0){printf(" ");}printf("%d",L[i][j]);}}printf("\n16次迭代右结果:");for(i=0;i<17;i++){printf("\nR[%d]:",i);for(j=0;j<32;j++){if(j%8==0){printf(" ");}printf("%d",R[i][j]);}}*/print();/*printf("\n二进制密文:");for(i=0;i<64;i++){printf("%d",c[i]);}*/printf("\n\t\t按0将此密文解密,1返回上一层,2返回主界面,其他键退出.....");scanf("%d",&t);if(t==0){int s[8];int a[64];Decryption(c,a);/*printf("\n解密后的二进制:");for(i=0;i<64;i++){printf("%d",a[i]);}*/To102(a,s,64);printf("\n\t\t解密结果:");for(i=0;i<8;i++){printf("%c",s[i]);}printf("\n\t\t按1加密,2解密,3退出");}else if(t==1){system("cls");show2();}else if(t==2){system("cls");show1();}else{exit(0);}}else if(num==2){char str1[20],str2[20];printf("\t\t请输入明文文件名:");scanf("%s",str1);reader(str1,s1);To2Bin(s1,m);printf("\t\t请输入密钥文件名:");scanf("%s",str2);reader(str2,s2);To2Bin(s2,d);SubKey(d);Encryption(m,c);print();printf("\n\t\t按0将此密文解密,1将密文存入文件,2返回主界面,其他键退出.....");scanf("%d",&t);if(t==0){int a[64];Decryption(c,a);/*printf("\n解密后的二进制:");for(i=0;i<64;i++){printf("%d",a[i]);}*/To102(a,s,64);printf("\n\t\t解密结果:");for(i=0;i<8;i++){printf("%c",s[i]);}printf("\n\t\t按1加密,2解密,3退出");}else if(t==1){int a[16];char str[30];FILE *fw;printf("\n\t\t请输入文件名:");scanf("%s",str);fw=fopen(str,"w");if(fw==NULL){printf("\n\t\t文件打开失败!\n");}else{To10(c,a,64);for(i=0;i<16;i++){fprintf(fw,"%X",a[i]);}}fclose(fw);printf("\n\t\t密文保存成功!按1加密,2解密,3退出");}else if(t==2){system("cls");show1();}else{exit(0);}}else if(num==3){system("cls");exit(0);}else{printf("\n\t\t输入不正确,请重新输入:");}}break;case 2:{system("cls");printf("\n\n\t\t------------------DES解密----------------");while(strlen(s1)!=8){printf("\n\n\n\t\t请输入密文(8):");scanf("%s",s1);}To2Bin(s1,m);while(strlen(s2)!=8){printf("\t\t请输入密钥(8):");scanf("%s",s2);}To2Bin(s2,d);SubKey(d);Decryption(m,c);print();printf("\n\t\t按1返回上一层,2返回主界面,其他键退出.....");scanf("%d",&t);if(t==1){system("cls");printf("\n\n\t\t---------------DES解密-------------");while(strlen(s1)!=8){printf("\n\n\t\t请输入密文(8):");scanf("%s",s1);}To2Bin(s1,m);while(strlen(s2)!=8){printf("\t\t请输入密钥(8):");scanf("%s",s);}To2Bin(s2,d);SubKey(d);Decryption(m,c);print();}else if(t==2){system("cls");show1();}else{exit(0);}}break;case 3:system("cls");exit(0);default:printf("输入不正确,请重新输入:");}}return 0;}说明:程序中有大部分的注释代码,去掉注释可查看各部分中间结果,如:十六轮子密钥,十六轮结果等程序运行主界面:加密界面:运行结果一:运行结果二:。

相关文档
最新文档