精华内容
下载资源
问答
  • DES代码实现(C++)

    千次阅读 2018-11-08 12:06:08
    文章目录DES代码实现效果分析代码分析使用到的数据类型DES.cppDES.hppmain.cpp DES代码实现 DES整体思路不难,大部分都是将bit数组的每一位以交换表对应位置的数字作为下标进行重排。本文仅进行代码分析,算法原理请...

    DES代码实现

    DES整体思路不难,大部分都是将bit数组的每一位以交换表对应位置的数字作为下标进行重排。本文仅进行代码分析,算法原理请留意我的另一篇算法描述的博客

    效果分析

    本程序实现的是输入一段任意字符串(无空格,可使用中文),通过加解密,可以输出密文和解密后得到的明文

    在这里插入图片描述

    代码分析

    使用到的数据类型

    为节省内存,本程序使用了bitset数据类型,每段明文被初始分解成64bit进行操作,用于S-盒数据过多,直接使用文件I/O进行读写,使用了二进制转十进制的转换函数strtol 和任意进制转二进制的函数_itoa_s() .

    ps : _itoa_s() 是visual stdio 支持的比较“安全”的itoa(),其他平台使用的是 itoa();
    运行代码前,请将DES.cpp 中Intial_Sbox 的filename 改成你本地的S-盒存储路径

    两个数据处理函数:

    ​ 1.StrToBit(string ) 将字符串转成二进制串,用于输入明文

    bitset<64>  DES::StrToBit(string a)
    {
    	bitset<64> bits;
    	for (int i = 0; i<8; ++i)
    		for (int j = 0; j<8; ++j)
    			bits[i * 8 + j] = ((a[i] >> j) & 1);
    	return bits;
    }
    

    ​ 2.BitToStr(bitset<64> a)将二进制串转成字符串,用于输出可视化的信息(如解密得到明文或者密文)

    string  DES::BitToStr(bitset<64> a)
    {
    	bitset<8> temp;
    	char **endptr = NULL;
    	int num;
    	string str = "";
    	for (int i = 0; i < 64; i++)
    	{
    		temp[i % 8] = a[i];
    		if (i % 8 == 7)
    		{
    			num = strtol(temp.to_string().c_str(), endptr, 2);
    			char a = num;
    			str += a;
    		}
    
    	}
    	return str;
    }
    

    S-盒数据,每个S-盒共有64个数据,共8个S-盒:

    14 4 13 1 2 15 11 8 3 10 6 12 5 9 0 7 0 15 7 4 15 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 12 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
    

    DES.cpp

    #include <iostream>
    #include <cstdlib>
    #include <fstream>
    #include "DES.hpp"
    using namespace std;
    
    DES::DES()
    {
    //初始化密钥
    	bitset<64> ckey("1010101010110101010010101010110101110101010101001001010100010101");
    	ChiperKey = ckey;
    //加载S-盒数据
    	Intial_Sbox();
    //生成子密钥
    	Generate_key();
    }
    void DES::initial(string str)
    {
    	while (str.length() < 8)
    	{
    		str += '0';
    	}
    	PlainText = StrToBit(str);
    }
    void DES::initialChiper(string str)
    {
    	ChiperText = StrToBit(str);
    }
    DES::~DES()
    {
    	SBox.clear();
    }
    void DES::IP(int num)
    {
    	int ip[64] = {58,50,42,34,26,18,10,2,60,52,44,36,28,20,12,4,62,54,
    		          46,38,30,22,14,6,64,56,48,40,32,24,16,8,57,49,41,33,
    				  25,17,9,1,59,51,43,35,27,19,11,3,61,53,45,37,29,21,
    				  13,5,63,55,47,39,31,23,15,7 };
    	int t;
    	bitset<64> temp;
    	if (num == 0)
    	{
    		temp = PlainText;
    	}
    	else
    	{
    		temp = ChiperText;
    	}
    
    	for (int i = 0; i < 64; i++)
    	{
    		t = ip[i]-1;
    		Temp[i] = temp[t];			
    	}
    }
    //IP置换
    string DES::IP1()
    {
    	int ip1[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 };
    	bitset<64> result;
    	for (int i = 0; i < 64; i++)
    	{
    		result[i] = Temp[ip1[i] - 1];
    	}
    
    	return BitToStr(result);
    }
    //Feistel轮函数,包括E扩展和S-盒压缩
    bitset<32> DES::Feistel(bitset<32>& R0, bitset<48>& k)
    {
    	//E-expend
    	int index[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};
    	bitset<48> E_expand;
    	int t;
    	for (int i = 0; i < 48; i++)
    	{
    		t = index[i] - 1;
    		E_expand[i] = R0[t];
    	}
    	//XOR
    	E_expand ^= k;
    
    	//divide into 8 group
    	bitset<6> group[8];
    	for (int i = 0; i < 8; i++)
    	{
    		for (int  j = 0; j < 6; j++)
    		{
    			group[i][j] = E_expand[j + i * 6];
    		}
    	}
    
    	// use long int strtol(const char *nptr, char **endptr, int base) 
    	//to translate any base number to decimalism 
    	// use char * itoa(int number , char *str,int base)
    	// to translate decimalism to any base number
    	bitset<6> row;
    	bitset<6> col;
    	bitset<6> row_and("100001");
    	bitset<6> col_and("011110");
    	bitset<6> temp_and("000001");
    	vector<bitset<4>> bit;
    	int select_row;
    	int select_col;
    	char **endptr = NULL;
    	for (int i = 0; i < 8; i++)
    	{
    		row = group[i] & row_and;
    		row = (row >> 5) | (row & temp_and);
    		col = group[i] & col_and;
    		col = col >> 1;
    		select_row = strtol(row.to_string().c_str(), endptr, 2);
    		select_col = strtol(col.to_string().c_str(), endptr, 2);
    		int num = S_Block(i, select_row, select_col);
    		char str[5] = "";
    		//translate num to binary number
    		_itoa_s(num, str,5, 2);//4 parameter
    		bitset<4> temp(str);
    		bit.push_back(temp);
    	}
    
    	bitset<32> feistel;
    	t = 0;
    	for (int i = 0; i < bit.size(); i++)
    	{
    		for (int j = 0; j < 4; j++)
    		{
    			feistel[t++] = bit[i][j];
    		}
    	}
    	bit.clear();
    	feistel = P_permutation(feistel);
    
    	return feistel;
    }
    
    
    void DES::Generate_key()
    {
    	int pc[56]  = { 57,49,41,33,25,17,9,1,58,50,42,34,26,18,10,
    				   2,59,51,43,35,27,19,11,3,60,52,44,36,63,55,
    				   47,39,31,23,15,7,62,54,46,38,30,22,14,6,61,
    				   53,45,37,29,21,13,5,28,20,12,4 };
    
    	int pc2[48] = { 14,17,11,24,1,5,3,28,15,6,21,10,23,19,12,4,
    					26,8,16,7,27,20,13,2,41,52,31,37,47,55,30,40,
    					51,45,33,48,44,49,39,56,34,53,46,42,50,36,29,32 };
    	bitset<28> C0;
    	bitset<28> D0;
    	int t;
    	for (int i = 0; i < 28; i++)
    	{
    		t     = pc[i]-1;
    		C0[i] = ChiperKey[t];
    		t     = pc[i + 28] - 1;
    		D0[i] = ChiperKey[t];
    	}
    	t = 1;
    	int shift;
    	while (t < 17)
    	{
    		
    		switch (t)
    		{
    		case 1:
    		case 2:
    		case 9:
    		case 16:shift = 1; break;
    		default:
    			shift = 2;
    			break;
    		}
    		int index;
    		C0 = (C0 >> (28 - shift))| (C0 << shift);
    		D0 = (D0 >> (28 - shift))| (D0 << shift);
    		for (int  i = 0; i < 48; i++)
    		{
    			index = pc2[i] - 1;
    			if (index < 28)
    			{
    				key[t][i] = C0[index];
    			}
    			else
    			{
    				key[t][i] = D0[index - 28];
    			}
    		}
    		t++;
    	}
    	
    
    }
    
    int DES::S_Block(int i,int row,int col)
    {
    	int index = i * 64 + row * 16 + col;
    	return SBox[index];
    }
    
    bitset<32> DES::P_permutation(bitset<32> &feistel)
    {
    	int p[32] = { 16,7,20,21,29,12,28,17,1,15,23,26,5,18,31,10,2,8,
    					24,14,32,27,3,9,19,13,30,6,22,11,4,25 };
    	bitset<32>temp;
    	for (int i = 0; i < 32; i++)
    	{
    		temp[i] = feistel[p[i] - 1];
    	}
    	return temp;
    }
    
    
    void DES::Transfer()
    {
    	bitset<32> L0;
    	bitset<32> R0;
    	bitset<32> L1;
    	bitset<32> R1;
    
    	for (int i = 0; i < 32; i++)
    	{
    		L0[i] = Temp[i];
    		R0[i] = Temp[i + 32];
    	}
    	int t = 1;
    	bitset<32> feistel;
    	while (t <= 16)
    	{
    		L1 = R0;
    		feistel = Feistel(R0, key[t]);
    		R1 = L0 ^ feistel;
    		L0 = L1;
    		R0 = R1;
    		t++;
    	}
    	for (int i = 0; i < 32; i++)
    	{
    		Temp[i] = R1[i];
    		Temp[i + 32] = L1[i];
    	}
    }
    
    void DES::Intial_Sbox()
    {
    //运行前,先修改为你的S-盒存储路径
    	string filename = "your absolute s-box path ";
    	ifstream inSboxData;
    	inSboxData.open(filename.c_str(), ios::in);
    	int t = 0;
    	int temp;
    	vector<int> VecTemp;
    	while (!inSboxData.eof())
    	{	
    		inSboxData >> temp;
    		SBox.push_back(temp);
    	}
    	inSboxData.close();
    }
    
    void DES::InverseTransfer()
    {
    	bitset<32> A;
    	bitset<32> B;
    	bitset<32> G;
    	bitset<32> H;
    	for (int i = 0; i < 32; i++)
    	{
    		A[i] = Temp[i];
    		B[i] = Temp[i + 32];
    	}
    	int t = 16;
    	while (t > 0)
    	{
    		G = B;//G = L_t = R_t-1;
    		H = A ^ Feistel(B, key[t]);//H = Li-1
    		B = H;// B = Lt;
    		A = G;// A = Rt;
    		t--;
    	}
    	for (int i = 0; i < 32; i++)
    	{
    		Temp[i] = H[i];
    		Temp[i + 32] = G[i];
    	}
    }
    bitset<64>  DES::StrToBit(string a)
    {
    	bitset<64> bits;
    	for (int i = 0; i<8; ++i)
    		for (int j = 0; j<8; ++j)
    			bits[i * 8 + j] = ((a[i] >> j) & 1);
    	return bits;
    }
    
    string  DES::BitToStr(bitset<64> a)
    {
    	bitset<8> temp;
    	char **endptr = NULL;
    	int num;
    	string str = "";
    	for (int i = 0; i < 64; i++)
    	{
    		temp[i % 8] = a[i];
    		if (i % 8 == 7)
    		{
    			num = strtol(temp.to_string().c_str(), endptr, 2);
    			char a = num;
    			str += a;
    		}
    
    	}
    	return str;
    }
    

    DES.hpp

    #ifndef DES_HPP
    #define DES_HPP
    #include <iostream>
    #include <string>
    #include <bitset>
    #include <vector>
    using namespace std;
    class DES
    {
    public:
    	DES();
    	~DES();
    	void initial(string str);
    	void initialChiper(string str);
    	void IP(int);
    	string IP1();
    	bitset<32> Feistel(bitset<32>& R0,bitset<48> &k);//轮函数
    	void Generate_key();
    	int S_Block(int i, int row, int col);
    	bitset<32> P_permutation(bitset<32> &feistel);//P置换
    	void Transfer();//加密过程的子密钥调度
    	void Intial_Sbox();//从本地加载S-盒数据
    	void InverseTransfer();//解密过程的子密钥调度
    	bitset<64> StrToBit(string );
    	string BitToStr(bitset<64> a);
    private:
    	std::bitset<64> PlainText;
    	std::bitset<64> ChiperText;
    	std::bitset<64> ChiperKey;
    	std::bitset<64> Temp;
    	std::bitset<48> key[17];
    	vector<int> SBox;	
    };
    #endif
    

    main.cpp

    #include <iostream>
    #include <string>
    #include "DES.hpp"
    using namespace std;
    int main()
    {
    	int sign;
    	cout << "input 0 to encode\ninput 1 to decode\ninput 2 to get the chiper text\n";
    	string a;
    	string b;
    	string str = "";
    	string plain = "";
    	DES des;
    	while (1)
    	{
    		cin >> sign;
    		if (sign == 0)
    		{
    			str = "";
    			cout << "please input the message" << endl;
    			cin >> a;
    			for (int i = 0; i < a.length(); i+= 8)
    			{
    				b = a.substr(i, 8);
    				des.initial(b);
    				des.IP(0);
    				des.Transfer();
    				str += des.IP1();
    			}
    			cerr << str << endl;
    		}
    		else if (sign == 1) {
    			if (str.length() == 0) {
    				cout << "please encode first" << endl;
    				continue;
    			}
    			plain = "";
    			for (int i = 0; i < str.length(); i += 8)
    			{
    				b = str.substr(i, 8);  
    				des.initialChiper(b);
    				des.IP(1);
    				des.InverseTransfer();
    				plain += des.IP1();
    			}
    			if (a.length() % 8 != 0)
    			{
    				plain = plain.substr(0, a.length());
    			}
    			cout << plain << endl;
    
    		}
    		else if (sign == 2) {
    			if (str.length() == 0) {
    				cout << "please encode first" << endl;
    				continue;
    			}
    			cout << str << endl;
    		}
    
    
    	}
    
    	return 0;
    }
    
    展开全文
  • AES和DES代码实现

    千次阅读 2018-08-22 19:53:12
    DES是一种对称加密算法,所谓对称加密算法即:加密和解密使用相同密钥的算法。因为DES使用56位密钥,以现代计算能力,24小时内即可被破解。虽然如此,在某些简单应用中,我们还是可以使用DES加密算法。 AES已经变成...

    DES是一种对称加密算法,所谓对称加密算法即:加密和解密使用相同密钥的算法。因为DES使用56位密钥,以现代计算能力,24小时内即可被破解。虽然如此,在某些简单应用中,我们还是可以使用DES加密算法。

    AES已经变成目前对称加密中最流行算法之一;AES可以使用128、192、和256位密钥,并且用128位分组加密和解密数据。

    package com.zyt;
    
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.lang.reflect.Array;
    import java.security.InvalidKeyException;
    import java.security.NoSuchAlgorithmException;
    import java.security.SecureRandom;
    import java.util.Arrays;
    
    import javax.crypto.Cipher;
    import javax.crypto.CipherInputStream;
    import javax.crypto.KeyGenerator;
    import javax.crypto.SecretKey;
    import javax.crypto.SecretKeyFactory;
    import javax.crypto.spec.DESKeySpec;
    import javax.crypto.spec.SecretKeySpec;
    
    /**
    /**
     * @ClassName: Test_DES_AES 
     * @Model : (所属模块名称)
     * @Description: (这里用一句话描述这个类的作用) 
     * @author Administrator 
     * @date 2017年6月20日 下午3:02:45 
     */
    public class Test_DES_AES {
    
        /**
        /**
         * main (这里用一句话描述这个方法的作用) 
         * @param args
         * void 
         * @ModifiedPerson Administrator
         * @date 2017年6月20日 下午3:02:45 
         */
        public static void main(String[] args) {
            //*****************************AES或DES加密 解密字符串*****************************
            //待加密内容  
            String str = "test";  
            //密码,长度要是8的倍数  
            String password = "12345678aa";  
            
            byte[] desEncryptResult = DESEncrypt(str.getBytes(), password);
            System.out.println("DES加密‘测试内容’的结果是:" + new String(desEncryptResult));
            
            byte[] desDecrypt = DESDecrypt(desEncryptResult, password);
            System.out.println("DES解密的结果是:" + new String(desDecrypt));
            
    
            byte[] aesEncrypt = AESEncrypt(str, password);
            System.out.println("AES加密‘测试内容’的结果是:" + new String(aesEncrypt));
            
            byte[] aesDecrypt = AESDecrypt(aesEncrypt, password);
            System.out.println("AES解密的结果是:" + new String(aesDecrypt));
            
            //String srcFilePath = "D:\\11.txt";//原文件
            String srcFilePath = "assets/11.txt";//原文件
    
            //***************************** DES加密 解密文件*****************************
            String encryptedFilePath = "assets/DES加密.txt";//加密后的文件
            String decryptedFilePath = "assets/DES解密.txt";//解密后的文件
            DESEncryptFile(srcFilePath, encryptedFilePath, password);
            DESDecryptFile(encryptedFilePath, decryptedFilePath, password);
            
            //***************************** AES加密 解密文件  *****************************
            String AESencryptedFilePath = "assets/AES加密.txt";//加密后的文件
            String AESdecryptedFilePath = "assets/AES解密.txt";//解密后的文件
            AESEncryptFile(srcFilePath, AESencryptedFilePath, password);
            AESDecryptFile(AESencryptedFilePath, AESdecryptedFilePath, password);
        }
        
        //  注意:DES加密和解密过程中,密钥password长度都必须是8的倍数
        public static byte[] DESEncrypt(byte[] datasource, String password){
            
            try {
                // DES算法要求有一个可信任的随机数源
                SecureRandom secureRandom = new SecureRandom();
                // 从原始密匙数据创建DESKeySpec对象
                DESKeySpec desKeySpec = new DESKeySpec(password.getBytes());
                // 创建一个密匙工厂,
                SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("DES");
                //把DESKeySpec转换成一个SecretKey对象
                SecretKey secretKey = secretKeyFactory.generateSecret(desKeySpec);
                // Cipher对象实际完成加密操作
                Cipher cipher = Cipher.getInstance("DES");
                //用密匙初始化Cipher对象  
                cipher.init(Cipher.ENCRYPT_MODE, secretKey, secureRandom);
                                       
                // 执行加密操作
                return cipher.doFinal(datasource);
                
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
            return null;
        }
        
        //  注意:DES加密和解密过程中,密钥password长度都必须是8的倍数
        public static byte[] DESDecrypt(byte[] encrypted, String password){
            try {
                // DES算法要求有一个可信任的随机数源
                SecureRandom secureRandom = new SecureRandom();
                // 创建一个DESKeySpec对象  
                DESKeySpec desKeySpec = new DESKeySpec(password.getBytes());
                // 创建一个密匙工厂  
                SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("DES");
                // 将DESKeySpec对象转换成SecretKey对象  
                SecretKey secretKey = secretKeyFactory.generateSecret(desKeySpec);
                // Cipher对象实际完成解密操作  
                Cipher cipher = Cipher.getInstance("DES");
                // 用密匙初始化Cipher对象  
                cipher.init(Cipher.DECRYPT_MODE, secretKey, secureRandom);
                // 真正开始解密操作  
                return cipher.doFinal(encrypted);
                
                
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
            
            return null;
        }
        
      //DES解密文件
        public static void DESDecryptFile(String encryptedFilePath, String decryptedFilePath, String password) {
            try {
                
                // DES算法要求有一个可信任的随机数源
                SecureRandom secureRandom = new SecureRandom();
                // 从原始密匙数据创建DESKeySpec对象
                DESKeySpec desKeySpec = new DESKeySpec(password.getBytes());
                // 创建一个密匙工厂,
                SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("DES");
                //把DESKeySpec转换成一个SecretKey对象
                SecretKey secretKey = secretKeyFactory.generateSecret(desKeySpec);
                // Cipher对象实际完成加密操作
                Cipher cipher = Cipher.getInstance("DES");
                //用密匙初始化Cipher对象  
                cipher.init(Cipher.DECRYPT_MODE, secretKey, secureRandom);
                
                //将文件中的数据读入
                FileInputStream fis = new FileInputStream(encryptedFilePath);
                //输出解密数据到文件
                FileOutputStream fos = new FileOutputStream(decryptedFilePath);
                
    
                //方法一:
                /*CipherInputStream cis = new CipherInputStream(fis, cipher);
                byte[] b = new byte[1024];
                int i = 0;
                while( (i = cis.read(b)) != -1 ){
                    fos.write(b, 0, i);
                }
                
                cis.close();
                */
                
    
                //方法二:
                byte[] bb = new byte[1024];
                int l = 0;
                while((l = fis.read(bb)) != -1){
                    byte[] doFinal = cipher.doFinal(Arrays.copyOfRange(bb, 0, l));
                    fos.write(doFinal, 0, doFinal.length);
                }
                
                fos.close();
                fis.close();
    
                System.out.println("DES解密文件结束");
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } 
            
        }
    
        //DES加密文件
        public static void DESEncryptFile(String srcFilePath, String desFilePath, String password) {
            try {
                
                // DES算法要求有一个可信任的随机数源
                SecureRandom secureRandom = new SecureRandom();
                // 从原始密匙数据创建DESKeySpec对象
                DESKeySpec desKeySpec = new DESKeySpec(password.getBytes());
                // 创建一个密匙工厂,
                SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("DES");
                //把DESKeySpec转换成一个SecretKey对象
                SecretKey secretKey = secretKeyFactory.generateSecret(desKeySpec);
                // Cipher对象实际完成加密操作
                Cipher cipher = Cipher.getInstance("DES");
                //用密匙初始化Cipher对象  
                cipher.init(Cipher.ENCRYPT_MODE, secretKey, secureRandom);
                
                
                //将文件中的数据读入
                FileInputStream fis = new FileInputStream(srcFilePath);
                //输出加密数据到文件
                FileOutputStream fos = new FileOutputStream(desFilePath);
                
                //方法一:
                /*CipherInputStream cis = new CipherInputStream(fis, cipher);
                byte[] b = new byte[1024];
                int i = 0;
                while( (i = cis.read(b)) != -1 ){
                    fos.write(b, 0, i);
                }
                cis.close();*/
                
                //方法二:
                byte[] bb = new byte[1024];
                int l = 0;
                while((l = fis.read(bb)) != -1){
                    byte[] doFinal = cipher.doFinal(Arrays.copyOfRange(bb, 0, l));
                    fos.write(doFinal, 0, doFinal.length);
                }
                
                fos.close();
                fis.close();
    
                System.out.println("DES加密文件结束");
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } 
            
        }
        
        public static byte[] AESEncrypt(String content, String password){
            try {
                KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
                keyGenerator.init(128, new SecureRandom(password.getBytes()));
                SecretKey secretKey = keyGenerator.generateKey();
                byte[] encoded = secretKey.getEncoded();
                SecretKeySpec secretKeySpec = new SecretKeySpec(encoded, "AES");
                //创建密码器
                Cipher cipher = Cipher.getInstance("AES");
                cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
                
                
                //真正的加密
                byte[] result = cipher.doFinal(content.getBytes("utf-8"));
                return result;
                
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
            return null;
        }
        
        public static byte[] AESDecrypt(byte[] content, String password){
            try {
                KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
                keyGenerator.init(128, new SecureRandom(password.getBytes()));
                SecretKey secretKey = keyGenerator.generateKey();
                byte[] encoded = secretKey.getEncoded();
                SecretKeySpec secretKeySpec = new SecretKeySpec(encoded, "AES");
                //创建解密器
                Cipher cipher = Cipher.getInstance("AES");
                cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
                
                
                //真正的解密
                byte[] result = cipher.doFinal(content);
                
                return result;
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return null;
            
        }
        
    
        //AES加密文件
        public static void AESEncryptFile(String srcFilePath, String AESencryptedFilePath, String password) {
           
            try { SecureRandom secureRandom = new SecureRandom(password.getBytes());
                KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
                keyGenerator.init(128, secureRandom);
                SecretKey secretKey = keyGenerator.generateKey();
                byte[] encoded = secretKey.getEncoded();
                SecretKeySpec secretKeySpec = new SecretKeySpec(encoded, "AES");
                Cipher cipher = Cipher.getInstance("AES");
                cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
                
                
                //将文件中的数据读入
                FileInputStream fis = new FileInputStream(srcFilePath);
                //输出加密数据到文件
                FileOutputStream fos = new FileOutputStream(AESencryptedFilePath);
                CipherInputStream cis = new CipherInputStream(fis, cipher);
                byte[] b = new byte[1024];
                int i = 0;
                while( (i = cis.read(b)) != -1 ){
                    fos.write(b, 0, i);
                }
                
                fos.close();
                cis.close();
                fis.close();
    
                System.out.println("AES加密文件结束");
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }   
    
    
        //AES解密文件
        public static void AESDecryptFile(String AESencryptedFilePath, String AESdecryptedFilePath, String password) {
            try { SecureRandom secureRandom = new SecureRandom(password.getBytes());
            KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
            keyGenerator.init(128, secureRandom);
            SecretKey secretKey = keyGenerator.generateKey();
            byte[] encoded = secretKey.getEncoded();
            SecretKeySpec secretKeySpec = new SecretKeySpec(encoded, "AES");
            Cipher cipher = Cipher.getInstance("AES");
            cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
            
            
            //将文件中的数据读入
            FileInputStream fis = new FileInputStream(AESencryptedFilePath);
            //输出解密数据到文件
            FileOutputStream fos = new FileOutputStream(AESdecryptedFilePath);
            CipherInputStream cis = new CipherInputStream(fis, cipher);
            byte[] b = new byte[1024];
            int i = 0;
            while( (i = cis.read(b)) != -1 ){
                fos.write(b, 0, i);
            }
            
            fos.close();
            cis.close();
            fis.close();
    
            System.out.println("AES解密文件结束");
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
            
        }
    
    }
    
    

    在Java项目中,上面的代码是完全能成功的,但在Android项目中,就会出现BadPaddingException: pad block corrupted in class SimpleCrypto in android,所以在Android中需要将秘钥固定SHA1PRNG,否则会因为秘钥不同而解密失败。

    //AES加密文件
        public static void AESEncryptFile(InputStream is, String AESencryptedFilePath, String password) {
           
            try {
                SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG", "Crypto");
                secureRandom.setSeed(password.getBytes());
                KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
                keyGenerator.init(128, secureRandom);
                SecretKey secretKey = keyGenerator.generateKey();
                byte[] encoded = secretKey.getEncoded();
                SecretKeySpec secretKeySpec = new SecretKeySpec(encoded, "AES");
                Cipher cipher = Cipher.getInstance("AES");
                cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
                
                
                //输出加密数据到文件
                FileOutputStream fos = new FileOutputStream(AESencryptedFilePath);
                CipherInputStream cis = new CipherInputStream(is, cipher);
                byte[] b = new byte[1024];
                int i = 0;
                while( (i = cis.read(b)) != -1 ){
                    fos.write(b, 0, i);
                }
                
                fos.close();
                cis.close();
    
                Log.i("?????", "AES加密文件结束");
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }   
    
    
        //AES解密文件
        public static void AESDecryptFile(InputStream is, String AESdecryptedFilePath, String password) {
            try { 
                //在Android中需要将秘钥固定SHA1PRNG,否则会因为秘钥不同而解密失败(BadPaddingException: pad block corrupted in class SimpleCrypto in android)
                SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG", "Crypto");
                secureRandom.setSeed(password.getBytes());
                KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
                keyGenerator.init(128, secureRandom);
                SecretKey secretKey = keyGenerator.generateKey();
                byte[] encoded = secretKey.getEncoded();
                SecretKeySpec secretKeySpec = new SecretKeySpec(encoded, "AES");
                Cipher cipher = Cipher.getInstance("AES");
                cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
                
                //输出解密数据到文件
                FileOutputStream fos = new FileOutputStream(AESdecryptedFilePath);
                CipherInputStream cis = new CipherInputStream(is, cipher);
                byte[] b = new byte[1024];
                int i = 0;
                while( (i = cis.read(b)) != -1 ){
                    fos.write(b, 0, i);
                }
                
                //方法二:
                /*byte[] bb = new byte[1024];
                int l = 0;
                while((l = is.read(bb)) != -1){
                    byte[] doFinal = cipher.doFinal(Arrays.copyOfRange(bb, 0, l));
                    fos.write(doFinal, 0, doFinal.length);
                }
                */
                fos.close();
                cis.close();
        
                System.out.println("AES解密文件结束");
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
            
        }
    

    #### YunSoul技术分享,扫码关注微信公众号##
      ——只要你学会了之前所不会的东西,只要今天的你强过了昨天的你,那你就一直是在进阶的路上了。
    展开全文
  • Des C实现代码

    热门讨论 2007-11-23 09:27:41
    Des C实现代码
  • DES算法代码实现

    千次阅读 2019-06-05 15:46:08
    DES是一个16轮的Feistel型结构密码,它的分组长度为64比特,用一个56比特的密钥来加密一个64比特的明文串,输出一个64比特的密文串。其中,使用密钥为64比特,实用56比特,另8位用作奇偶校验。加密的过程是先对64位...

    DES是一个16轮的Feistel型结构密码,它的分组长度为64比特,用一个56比特的密钥来加密一个64比特的明文串,输出一个64比特的密文串。其中,使用密钥为64比特,实用56比特,另8位用作奇偶校验。加密的过程是先对64位明文分组进行初始置换,然后分左、右两部分分别经过16轮迭代,然后再进行循环移位与变换,最后进行逆变换得出密文。加密与解密使用相同的密钥,因而它属于对称密码体制。假设输入的明文数据是64比特。首先经过初始置换IP后把其左半部分32比特记为L0,右半部分32比特记为R0,即成了置换后的输入;然后把R0与密钥产生器产生的子密钥k1进行运算,其结果计为f (R0,k1);再与L0进行摸2加得到L0+f (R0 , k1), 把R0记为L1放在左边,而把L0+f (R0 , k1)记为R1放在右边,从而完成了第一轮迭代运算。在此基础上,重复上述的迭代过程,一直迭代至第16轮。所得的第16轮迭代结果左右不交换,即L15+f (R15 , k16)记为R16,放在左边,而R15记为L16放在右边,成为预输出,最后经过初始置换的逆置换IP-1运算后得到密文。详细的算法解析在网上有很多,笔者在这里就不一一介绍,核心处理在于f函数,编程过程中谨慎一点儿别抄错数字之类的,一般都没问题。解密过程是加密的逆向,只需要在加密过程中把十六轮子秘钥全部记录下来,在解密时反过来使用一轮,其他的处理算法如出一辙,就能正确得出结果。直接在下面贴出代码(代码有局限,只能接受十六位十六进制数作为明文,十六位十六进制数作为初始秘钥,对于中文的加密以及任意长度的字符串的加密,有需要的朋友可以自行修改代码实现)。初始秘钥和明文从文件中读取,会在后面附上截图。

    // DES.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
    //
    
    #include "pch.h"
    #include <iostream>
    #include <fstream>
    #include <string>
    using namespace std;
    
    //记录所有的子秘钥
    int eachKey[16][48];
    
    int boxS[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}
    	}
    };
    
    //记录左移次数
    int leftMove[16] = { 1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1 };
    
    int C[28] = { 0 }, D[28] = { 0 };
    int L[32] = { 1 }, R[32] = { 1 };
    
    //p置换
    int P[32] = {16,7,20,21,29,12,28,17,1,15,23,26,5,18,31,10,2,8,24,14,32,27,3,9,19,13,30,6,22,11,4,25};
    
    //E扩展
    int biteChoiceLabel[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};
    
    //秘钥置换
    int keySwap[8][6] = { {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} };
    
    //密文初始置换
    int IP[8][8] = { {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 }};
    
    //密文逆置换
    int IP_1[8][8] = { {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} };
    
    //64->56选择
    int PC_1[8][7] = { {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} };
    
    
    //初始置换IP
    void InitIP(int **input) {
    	int s[64];
    	int c = 0;
    	for(int i = 0;i<8;i++)
    		for (int j = 0; j < 8; j++) {
    			s[c++] = input[i][j];
    		}
    	int **newIP = new int *[8];
    	for (int i = 0; i < 8; i++)
    		newIP[i] = new int[8];
    
    	for (int i = 0; i < 8; i++) {
    		for (int j = 0; j < 8; j++) {
    			int loc = IP[i][j] - 1; //因为从1开始,这里下标减一
    			newIP[i][j] = s[loc];
    		}
    	}
    	int l = 0, m = 0;
    	for(int i = 0;i < 8;i++)
    		for (int j = 0; j < 8; j++) {
    			if (i * 8 + j < 32)
    				L[l++] = newIP[i][j];
    			else
    				R[m++] = newIP[i][j];
    		}
    }
    
    //逆初始置换
    void reverse() {
    	int temp[64];
    	int a[64];
    	for (int i = 0; i < 32; i++) {
    		temp[i] = L[i];
    		temp[i + 32] = R[i];
    	}
    	
    	int l = 0, m = 0;
    	for (int i = 0; i < 8; i++) {
    		for (int j = 0; j < 8; j++) {
    			a[l++] = temp[IP_1[i][j] - 1];
    		}
    	}
    	l = 0;
    	for (int i = 0; i < 64; i++)
    		if (i < 32)
    			L[l++] = a[i];
    		else
    			R[m++] = a[i];
    }
    
    //操作函数f
    int *f(int n, int flag) {
    	int *result = new int[32];
    	int a[48];
    	int temp[56];
    	int newKey[48];
    	for (int i = 0; i < 28; i++) {
    		temp[i] = C[i];
    		temp[i + 28] = D[i];
    	}
    	int l = 0;
    	if (flag == 0) {
    		for (int i = 0; i < 8; i++) {
    			for (int j = 0; j < 6; j++) {
    				int loc = keySwap[i][j];
    				newKey[l++] = temp[loc - 1];
    				eachKey[15-n][l - 1] = newKey[l - 1];   //记录加密时的全部子秘钥
    			}
    		}
    	}
    	else {
    		for (int i = 0; i < 48; i++)
    			newKey[i] = eachKey[n][i];
    	}
    	int newR[48];
    	for (int i = 0; i < 48; i++)
    		newR[i] = R[biteChoiceLabel[i]-1];
    	for (int i = 0; i < 48; i++)
    		a[i] = (newKey[i]+newR[i])%2;
    	int b[8][6];
    	int r[8];
    	l = 0;
    	int m = 0;
    	int k = 0;
    	for (int i = 0; i < 48; i++) {
    		b[l][m] = a[i];
    		if ((i + 1) % 6 == 0) {
    			int first = b[l][0] * 2 + b[l][5];
    			int second = b[l][1] * 8 + b[l][2] * 4 + b[l][3] * 2 + b[l][4];
    			r[l] = boxS[l][first][second];
    			l++;
    			m = 0;
    		}
    		else
    			m++;
    	}
    	int c[8][4];
    	l = 0;
    	for (int i = 0; i < 8; i++) {
    		int ti = 0;
    		int aa = r[i] / 8;
    		int bb = (r[i] - aa * 8) / 4;
    		int cc = (r[i] - aa * 8 - bb * 4) / 2;
    		int dd = r[i] - aa * 8 - bb * 4 - cc * 2;
    		c[i][0] = aa;
    		c[i][1] = bb;
    		c[i][2] = cc;
    		c[i][3] = dd;
    	}
    	int tempP[32];
    	for (int i = 0; i < 8; i++)
    		for (int j = 0; j < 4; j++) {
    			tempP[l++] = c[i][j];
    		}
    	for (int i = 0; i < 32; i++)
    		result[i] = tempP[P[i] - 1];
    	return result;
    }
    
    //交换处理
    void swap(int n, int flag) {
    	int tempL[32], tempR[32];
    	int *Result = new int[32];
    	//数据备份
    	for (int i = 0; i < 32; i++) {
    		tempR[i] = R[i];
    		tempL[i] = L[i];
    	}
    	Result = f(n, flag);
    	//数据更新计
    	for (int i = 0; i < 32; i++) {
    		L[i] = tempR[i];
    		R[i] = (tempL[i] + Result[i]) % 2;
    	}
    	if (n == 15) {
    		for (int i = 0; i < 32; i++) {
    			int temp = L[i];
    			L[i] = R[i];
    			R[i] = temp;
    		}
    	}
    }
    
    
    
    //产生第一轮秘钥(64位->56位)
    int **firstKey(int **key) {
    	int **fk = new int *[8];
    	for (int i = 0; i < 8; i++)
    		fk[i] = new int[7];
    	int nk[64];
    	int s = 0;
    	int l = 0, m = 0;
    	for (int i = 0; i < 8; i++)
    		for (int j = 0; j < 8; j++)
    			nk[s++] = key[i][j];
    	for (int i = 0; i < 8; i++) {
    		for (int j = 0; j < 7; j++) {
    			int loc = PC_1[i][j] - 1;
    			fk[i][j] = nk[loc];
    			if (l < 28)
    				C[l++] = nk[loc];
    			else
    				D[m++] = nk[loc];
    		}
    	}
    	return fk;
    }
    
    //循环产生子秘钥
    void nextKeyLeft(int n) {
    	int times = leftMove[n];
    	for (int i = 0; i < times; i++) {
    		int C0 = C[0];
    		int D0 = D[0];
    		for (int j = 1; j < 28; j++) {
    			C[j - 1] = C[j];
    			D[j - 1] = D[j];
    		}
    		C[27] = C0;
    		D[27] = D0;
    	}
    }
    
    
    //十六进制输入转二进制
    int **hxTobin(string input) {
    	int a[64];
    	int x[16];
    	int **init_letters = new int *[8];
    	for (int i = 0; i < 8; i++)
    		init_letters[i] = new int[8];
    	int j = 0;
    	for (int i = 0; i < 16; i++) {
    		if (input[i] >= '0' && input[i] <= '9')
    			x[i] = input[i] - 48;
    		else if (input[i] >= 'A' && input[i] <= 'Z')
    			x[i] = input[i] - 55;
    		else
    			x[i] = input[i] - 87;
    	}
    	for (int i = 0; i < 16; i++) {
    		int aa = x[i] / 8;
    		int bb = (x[i] - aa * 8) / 4;
    		int cc = (x[i] - aa * 8 - bb * 4) / 2;
    		int dd = x[i] - aa * 8 - bb * 4 - cc * 2;
    		a[j] = aa;
    		a[j + 1] = bb;
    		a[j + 2] = cc;
    		a[j + 3] = dd;
    		j = j + 4;
    	}
    	
    	int l = 0;
    	for (int i = 0; i < 8; i++) {
    		for (j = 0; j < 8; j++) {
    			init_letters[i][j] = a[l++];
    		}
    	}
    	return init_letters;
    }
    
    //二进制密文转十六进制密文
    string binTohx(int a[]) {
    	string res;
    	res.resize(16);
    	int j = 0;
    	for (int i = 0; i < 64; i+=4) {
    		int b = a[i] * 8 + a[i + 1] * 4 + a[i + 2] * 2 + a[i + 3];
    		if (b < 10)
    			res[j] = b+'0';
    		else{
    			switch (b) {
    			case 10:
    				res[j] = 'a';
    				break;
    			case 11:
    				res[j] = 'b';
    				break;
    			case 12:
    				res[j] = 'c';
    				break;
    			case 13:
    				res[j] = 'd';
    				break;
    			case 14:
    				res[j] = 'e';
    				break;
    			case 15:
    				res[j] = 'f';
    				break;
    			}
    		}
    		j++;
    	}
    	return res;
    }
    
    //解密过程
    void decode(string res) {
    	int **re = new int *[8];
    	for (int i = 0; i < 8; i++)
    		re[i] = new int[8];
    	re = hxTobin(res);
    	InitIP(re);
    	for (int i = 0; i < 16; i++) {
    		swap(i, 1);
    	}
    	reverse();
    	int a[64];
    	for (int i = 0; i < 32; i++) {
    		a[i] = L[i];
    		a[i + 32] = R[i];
    	}
    	string input;
    	input = binTohx(a);
    	std::cout << input << endl << endl;;
    }
    
    
    int main()
    {
    	string letters;
    	string keys;
    	string words;
    	char flag='n';
    	int miwen[64];
    	ifstream file;
    	file.open("test.txt");
    	int **fir = new int *[8];
    	for (int i = 0; i < 8; i++)
    		fir[i] = new int[8];
    	cout << "--------- Begin(y/n)? ----------" << endl;
    	cin >> flag;
    	while (flag == 'y' &&!file.eof()) {
    		std::cout << "---------- 读入密文: ----------" << endl;
    		if (!file) {
    			std::cout << "---------- 读取失败 ----------" << endl;
    			exit(0);
    		}
    		getline(file, letters);
    		std::cout << "明文: " << letters << endl << endl;
    		std::cout << "---------- 读入秘钥: ----------" << endl;
    		getline(file, keys);
    		std::cout << "秘钥: " << keys << endl << endl;
    		fir = hxTobin(keys);
    		int **getLetters = new int *[8];
    		for (int i = 0; i < 8; i++)
    			getLetters[i] = new int[8];
    		getLetters = hxTobin(letters);
    		InitIP(getLetters);
    		int **fk = new int *[8];
    		for (int i = 0; i < 8; i++)
    			fk[i] = new int[7];
    		for (int i = 0; i <= 16; i++) {
    			if (i == 0) {
    				fk = firstKey(fir);
    			}
    			else {
    				nextKeyLeft(i - 1);
    				swap(i - 1, 0);
    			}
    		}
    		reverse();
    		int k = 0;
    		for (int i = 0; i < 32; i++) {
    			miwen[k++] = L[i];
    		}
    		for (int i = 0; i < 32; i++) {
    			miwen[k++] = R[i];
    		}
    		words = binTohx(miwen);
    		std::cout << "密文: " << words << endl;
    		std::cout << "----------  解密中  ----------" << endl;
    		decode(words);
    		std::cout << "-----------  继续(y/n) ---------" << endl;
    		std::cin >> flag;
    	}
    	std::cout << "---------- End! ----------" << endl;
    	return 0;
    }
    

    测试数据如下图:奇数行是明文,偶数行是对应的测试秘钥

    运行截图:

    尊重原作,转载请注明,转载自:https://blog.csdn.net/kr2563

    展开全文
  • DES算法实现代码有界面,亲自调试过,无错误
  • DES代码C语言实现

    2018-04-30 21:07:23
    用C语言实现DES(数据加密算法)的一个例子,密文和密钥都是8个字符。
  • 利用DES代码实现下面功能: 1 给定某个Sbox的输入差分情况下,计算所有输入对和所有Sbox输出差分的分布情况 2 统计DES算法在密钥固定情况,输入明文改变1位、2位,。。。64位时。输出密文位数改变情况。 3 统计...

    利用DES源代码实现下面功能: 

    1 给定某个Sbox的输入差分情况下,计算所有输入对和所有Sbox输出差分的分布情况 

    2 统计DES算法在密钥固定情况,输入明文改变1位、2位,。。。64位时。输出密文位数改变情况。 

    3 统计DES算法在明文固定情况,密文改变1位、2位,。。。64位时。输出密文位数改

    下载地址:https://download.csdn.net/download/qq_34868086/10390350?utm_source=bbsseo

    展开全文
  • DES算法Java实现代码

    2019-04-08 17:36:47
    DES算法Java实现代码;网络安全技术及应用;java图形界面实现
  • DES算法代码实现(C语言)

    千次阅读 2020-08-16 16:34:41
    通过C语言模拟DES算法的整个加密过程 初始明文(64位),首先通过IP置换表进行置换,然后将置换后的结果分成左半部分L0(32位)和右半部分R0(32位),右半部分R0直接进行交换为下一轮的L1,左半部分L0与作为输入...
  • JAVA实现DES加密实现(代码)

    千次阅读 2020-02-23 20:29:05
    private static String ALGORITHM = "DES"; static { try { //生成DES算法对象 KeyGenerator generator = KeyGenerator.getInstance(ALGORITHM); //运用SHA1安全策略 SecureRandom secureRandom = ...
  • DES代码讲解

    千次阅读 2017-10-04 00:12:31
    public class DESDemo { /* * DES加密介绍 DES是一种对称加密算法,所谓对称加密算法即:加密和解密使用相同密钥的算法。...虽然如此,在某些简单应用中,我们还是可以使用DES加密算法,本文简单讲解DES
  • DES算法的C实现代码

    千次阅读 2013-11-13 13:05:38
    英文网页:DES算法的C实现代码 中文网页:DES算法的C实现代码(详解)
  •   1、本文中DES加解密基本流程及S盒等参数参照自杨波《现代密码学(第四版)》,实现过程均为自编函数。   2、为了说明64bit密钥中,只有56bit真正参与加解密过程,对网上代码中的密钥生成过程做出了修改,详见...
  • DES加密与解密原理及C++代码实现

    万次阅读 多人点赞 2019-08-17 20:21:13
    一.DES算法简介 DES(Data Encryption Standard)是目前最为流行的加密算法之一。 对称性:DES是对称的,也就是说它使用同一个密钥来加密和解密数据。与此相对的是RSA加密算法,是一种非对称加密算法 分组性:DES还是...
  • DES密码 中 S盒的代码实现

    千次阅读 2020-04-13 20:10:16
    代码实现(C#) using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace S_box { class Program { //S 盒的简单实现,...
  • 大多数语言自身实现了des加密解密函数,而在php里面并没有直接实现的函数,这里我将介绍PHP代码实现DES加密解密算法。 在PHP中实现DES加密解密,需要加载一个外部扩展模块mcrypt模块,默认安装的PHP并没有带该...
  • 利用加密算法DES实现java代码加密  传统的C/C++自动带有保护机制,但java不同,只要使用反编译工具,代码很容易被暴露,这里需要了解的就是Java的ClassLoader对象。  Java运行时装入字节码的机制隐含地意味着...
  • 3DES(或称为Triple DES)是三重数据加密算法(TDEA,Triple Data Encryption ...3DES即是设计用来提供一种相对简单的方法,即通过增加DES的密钥长度来避免类似的攻击,而不是设计一种全新的块密码算法。  3DE
  • java实现DES加密源代码

    千次阅读 2013-09-29 17:06:19
    JAVA实现DES加密 DES加密介绍  DES是一种对称加密算法,所谓对称加密算法即:加密和解密使用相同密钥的算法。DES加密算法出自IBM的研究,后来被美国政府正式采用,之后开始广泛流传,但是近些年使用越来越少,...
  • 用C代码实现des加密算法

    千次阅读 2014-12-17 17:39:26
    /**********************************************************************...> File Name: Des.c > Author:TAO.HU > Mail: > Created Time: 2014年12月17日 星期三 15时58分30秒 ***********************************
  • 本文主要是对《信息安全技术》的DES算法实验作业的一些总结,不会着重地介绍算法原理,而会在算法实现过程中给出自己的理解(因为有些部分我也不知道正确与否,如有错误请指教)。文章中出现的原理介绍和配图,均...
  • 3DES加密java的实现代码 加密算法的实现2006-10-29 10:12:07阅读249评论0字号:大中小 3DES加密java的实现代码   <br />public void getKey(String strKey) { try{ ...
  • des算法的C语言实现,其中含有源代码,经测试结果准确
  • DES加密图解、DES的java实现代码、3DES的java实现代码
  • DES算法实现

    千次阅读 2018-10-31 10:30:50
    Web Security Assignment 1 实验需求 算法原理 总体结构 ...DES算法为密码体制中的对称密码体制,又被称为美国数据加密标准,是1972年美国IBM公司研制的对称密码体制加密算法。 明文按64位进...
  • DES的差分分布表 C代码实现

    千次阅读 2018-03-17 11:41:39
    //根据des把结果写成8个6比特串的并联,每一个s盒把6比特映射到4比特 //则array是输入比特串是6位 brray是输出比特串是4位,crray是s盒4X16 FILE *fp; if((fp=fopen("差分分布统计表","w"))==NULL) { //w 打开...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 40,355
精华内容 16,142
关键字:

des代码实现