OpenSSL中对称加密算法DES常用函数使用举例

主要包括3个文件:

1. cryptotest.h:

#ifndef _CRYPTOTEST_H_
#define _CRYPTOTEST_H_

#include <string>

using namespace std;

typedef enum {
	GENERAL = 0,
	ECB,
	CBC,
	CFB,
	OFB,
	TRIPLE_ECB,
	TRIPLE_CBC
}CRYPTO_MODE;

string DES_Encrypt(const string cleartext, const string key, CRYPTO_MODE mode);
string DES_Decrypt(const string ciphertext, const string key, CRYPTO_MODE mode);

#endif //_CRYPTOTEST_H_

2. destest.cpp:

#include <iostream>
#include <string>
#include <vector>
#include <openssl/des.h>
#include "cryptotest.h"

using namespace std;

static unsigned char cbc_iv[8] = {‘0‘, ‘1‘, ‘A‘, ‘B‘, ‘a‘, ‘b‘, ‘9‘, ‘8‘};

string DES_Encrypt(const string cleartext, const string key, CRYPTO_MODE mode)
{
	string strCipherText;

	switch (mode) {
	case GENERAL:
	case ECB:
		{
			DES_cblock keyEncrypt;
			memset(keyEncrypt, 0, 8);

			if (key.length() <= 8)
				memcpy(keyEncrypt, key.c_str(), key.length());
			else
				memcpy(keyEncrypt, key.c_str(), 8);

			DES_key_schedule keySchedule;
			DES_set_key_unchecked(&keyEncrypt, &keySchedule);	

			const_DES_cblock inputText;
			DES_cblock outputText;
			vector<unsigned char> vecCiphertext;
			unsigned char tmp[8];

			for (int i = 0; i < cleartext.length() / 8; i ++) {
				memcpy(inputText, cleartext.c_str() + i * 8, 8);
				DES_ecb_encrypt(&inputText, &outputText, &keySchedule, DES_ENCRYPT);
				memcpy(tmp, outputText, 8);

				for (int j = 0; j < 8; j++)
					vecCiphertext.push_back(tmp[j]);
			}

			if (cleartext.length() % 8 != 0) {
				int tmp1 = cleartext.length() / 8 * 8;
				int tmp2 = cleartext.length() - tmp1;
				memset(inputText, 0, 8);
				memcpy(inputText, cleartext.c_str() + tmp1, tmp2);

				DES_ecb_encrypt(&inputText, &outputText, &keySchedule, DES_ENCRYPT);
				memcpy(tmp, outputText, 8);

				for (int j = 0; j < 8; j++)
					vecCiphertext.push_back(tmp[j]);
			}

			strCipherText.clear();
			strCipherText.assign(vecCiphertext.begin(), vecCiphertext.end());
		}
		break;
	case CBC:
		{
			DES_cblock keyEncrypt, ivec;
			memset(keyEncrypt, 0, 8);

			if (key.length() <= 8)
				memcpy(keyEncrypt, key.c_str(), key.length());
			else
				memcpy(keyEncrypt, key.c_str(), 8);

			DES_key_schedule keySchedule;
			DES_set_key_unchecked(&keyEncrypt, &keySchedule);	

			memcpy(ivec, cbc_iv, sizeof(cbc_iv));

			int iLength = cleartext.length() % 8 ? (cleartext.length() / 8 + 1) * 8 : cleartext.length();
			unsigned char* tmp = new unsigned char[iLength + 16];
			memset(tmp, 0, iLength);

			DES_ncbc_encrypt((const unsigned char*)cleartext.c_str(), tmp, cleartext.length()+1, &keySchedule, &ivec, DES_ENCRYPT);

			strCipherText = (char*)tmp;

			delete [] tmp;
		}
		break;
	case CFB:
		{
			DES_cblock keyEncrypt, ivec;
			memset(keyEncrypt, 0, 8);

			if (key.length() <= 8)
				memcpy(keyEncrypt, key.c_str(), key.length());
			else
				memcpy(keyEncrypt, key.c_str(), 8);

			DES_key_schedule keySchedule;
			DES_set_key_unchecked(&keyEncrypt, &keySchedule);	

			memcpy(ivec, cbc_iv, sizeof(cbc_iv));

			unsigned char* outputText = new unsigned char[cleartext.length()];
			memset(outputText, 0, cleartext.length());

			const unsigned char* tmp = (const unsigned char*)cleartext.c_str();

			DES_cfb_encrypt(tmp, outputText, 8, cleartext.length(), &keySchedule, &ivec, DES_ENCRYPT);

			strCipherText = (char*)outputText;

			delete [] outputText;
		}
		break;
	case TRIPLE_ECB:
		{
			DES_cblock ke1, ke2, ke3;
			memset(ke1, 0, 8);
			memset(ke2, 0, 8);
			memset(ke2, 0, 8);

			if (key.length() >= 24) {
				memcpy(ke1, key.c_str(), 8);
				memcpy(ke2, key.c_str() + 8, 8);
				memcpy(ke3, key.c_str() + 16, 8);
			} else if (key.length() >= 16) {
				memcpy(ke1, key.c_str(), 8);
				memcpy(ke2, key.c_str() + 8, 8);
				memcpy(ke3, key.c_str() + 16, key.length() - 16);
			} else if (key.length() >= 8) {
				memcpy(ke1, key.c_str(), 8);
				memcpy(ke2, key.c_str() + 8, key.length() - 8);
				memcpy(ke3, key.c_str(), 8);
			} else {
				memcpy(ke1, key.c_str(), key.length());
				memcpy(ke2, key.c_str(), key.length());
				memcpy(ke3, key.c_str(), key.length());
			}

			DES_key_schedule ks1, ks2, ks3;
			DES_set_key_unchecked(&ke1, &ks1);
			DES_set_key_unchecked(&ke2, &ks2);
			DES_set_key_unchecked(&ke3, &ks3);

			const_DES_cblock inputText;
			DES_cblock outputText;
			vector<unsigned char> vecCiphertext;
			unsigned char tmp[8];

			for (int i = 0; i < cleartext.length() / 8; i ++) {
				memcpy(inputText, cleartext.c_str() + i * 8, 8);
				DES_ecb3_encrypt(&inputText, &outputText, &ks1, &ks2, &ks3, DES_ENCRYPT);
				memcpy(tmp, outputText, 8);

				for (int j = 0; j < 8; j++)
					vecCiphertext.push_back(tmp[j]);
			}

			if (cleartext.length() % 8 != 0) {
				int tmp1 = cleartext.length() / 8 * 8;
				int tmp2 = cleartext.length() - tmp1;
				memset(inputText, 0, 8);
				memcpy(inputText, cleartext.c_str() + tmp1, tmp2);

				DES_ecb3_encrypt(&inputText, &outputText, &ks1, &ks2, &ks3, DES_ENCRYPT);
				memcpy(tmp, outputText, 8);

				for (int j = 0; j < 8; j++)
					vecCiphertext.push_back(tmp[j]);
			}

			strCipherText.clear();
			strCipherText.assign(vecCiphertext.begin(), vecCiphertext.end());
		}
		break;
	case TRIPLE_CBC:
		{
			DES_cblock ke1, ke2, ke3, ivec;
			memset(ke1, 0, 8);
			memset(ke2, 0, 8);
			memset(ke2, 0, 8);

			if (key.length() >= 24) {
				memcpy(ke1, key.c_str(), 8);
				memcpy(ke2, key.c_str() + 8, 8);
				memcpy(ke3, key.c_str() + 16, 8);
			} else if (key.length() >= 16) {
				memcpy(ke1, key.c_str(), 8);
				memcpy(ke2, key.c_str() + 8, 8);
				memcpy(ke3, key.c_str() + 16, key.length() - 16);
			} else if (key.length() >= 8) {
				memcpy(ke1, key.c_str(), 8);
				memcpy(ke2, key.c_str() + 8, key.length() - 8);
				memcpy(ke3, key.c_str(), 8);
			} else {
				memcpy(ke1, key.c_str(), key.length());
				memcpy(ke2, key.c_str(), key.length());
				memcpy(ke3, key.c_str(), key.length());
			}

			DES_key_schedule ks1, ks2, ks3;
			DES_set_key_unchecked(&ke1, &ks1);
			DES_set_key_unchecked(&ke2, &ks2);
			DES_set_key_unchecked(&ke3, &ks3);

			memcpy(ivec, cbc_iv, sizeof(cbc_iv));

			int iLength = cleartext.length() % 8 ? (cleartext.length() / 8 + 1) * 8 : cleartext.length();
			unsigned char* tmp = new unsigned char[iLength + 16];
			memset(tmp, 0, iLength);

			DES_ede3_cbc_encrypt((const unsigned char*)cleartext.c_str(), tmp, cleartext.length()+1, &ks1, &ks2, &ks3, &ivec, DES_ENCRYPT);

			strCipherText = (char*)tmp;

			delete [] tmp;
		}
		break;
	}

	return strCipherText;
}

string DES_Decrypt(const string ciphertext, const string key, CRYPTO_MODE mode)
{
	string strClearText;

	switch (mode) {
	case GENERAL:
	case ECB:
		{
			DES_cblock keyEncrypt;
			memset(keyEncrypt, 0, 8);

			if (key.length() <= 8)
				memcpy(keyEncrypt, key.c_str(), key.length());
			else
				memcpy(keyEncrypt, key.c_str(), 8);

			DES_key_schedule keySchedule;
			DES_set_key_unchecked(&keyEncrypt, &keySchedule);	

			const_DES_cblock inputText;
			DES_cblock outputText;
			vector<unsigned char> vecCleartext;
			unsigned char tmp[8];

			for (int i = 0; i < ciphertext.length() / 8; i ++) {
				memcpy(inputText, ciphertext.c_str() + i * 8, 8);
				DES_ecb_encrypt(&inputText, &outputText, &keySchedule, DES_DECRYPT);
				memcpy(tmp, outputText, 8);

				for (int j = 0; j < 8; j++)
					vecCleartext.push_back(tmp[j]);
			}

			if (ciphertext.length() % 8 != 0) {
				int tmp1 = ciphertext.length() / 8 * 8;
				int tmp2 = ciphertext.length() - tmp1;
				memset(inputText, 0, 8);
				memcpy(inputText, ciphertext.c_str() + tmp1, tmp2);

				DES_ecb_encrypt(&inputText, &outputText, &keySchedule, DES_DECRYPT);
				memcpy(tmp, outputText, 8);

				for (int j = 0; j < 8; j++)
					vecCleartext.push_back(tmp[j]);
			}

			strClearText.clear();
			strClearText.assign(vecCleartext.begin(), vecCleartext.end());
		}
		break;
	case CBC:
		{
			DES_cblock keyEncrypt, ivec;
			memset(keyEncrypt, 0, 8);

			if (key.length() <= 8)
				memcpy(keyEncrypt, key.c_str(), key.length());
			else
				memcpy(keyEncrypt, key.c_str(), 8);

			DES_key_schedule keySchedule;
			DES_set_key_unchecked(&keyEncrypt, &keySchedule);	

			memcpy(ivec, cbc_iv, sizeof(cbc_iv));

			int iLength = ciphertext.length() % 8 ? (ciphertext.length() / 8 + 1) * 8 : ciphertext.length();
			unsigned char* tmp = new unsigned char[iLength];
			memset(tmp, 0, iLength);

			DES_ncbc_encrypt((const unsigned char*)ciphertext.c_str(), tmp, ciphertext.length()+1, &keySchedule, &ivec, DES_DECRYPT);

			strClearText = (char*)tmp;

			delete [] tmp;
		}
		break;
	case CFB:
		{
			DES_cblock keyEncrypt, ivec;
			memset(keyEncrypt, 0, 8);

			if (key.length() <= 8)
				memcpy(keyEncrypt, key.c_str(), key.length());
			else
				memcpy(keyEncrypt, key.c_str(), 8);

			DES_key_schedule keySchedule;
			DES_set_key_unchecked(&keyEncrypt, &keySchedule);	

			memcpy(ivec, cbc_iv, sizeof(cbc_iv));

			unsigned char* outputText = new unsigned char[ciphertext.length()];
			memset(outputText, 0, ciphertext.length());

			const unsigned char* tmp = (const unsigned char*)ciphertext.c_str();

			DES_cfb_encrypt(tmp, outputText, 8, 32/*ciphertext.length() - 16*/, &keySchedule, &ivec, DES_DECRYPT);

			strClearText = (char*)outputText;

			delete [] outputText;
		}
		break;
	case TRIPLE_ECB:
		{
			DES_cblock ke1, ke2, ke3;
			memset(ke1, 0, 8);
			memset(ke2, 0, 8);
			memset(ke2, 0, 8);

			if (key.length() >= 24) {
				memcpy(ke1, key.c_str(), 8);
				memcpy(ke2, key.c_str() + 8, 8);
				memcpy(ke3, key.c_str() + 16, 8);
			} else if (key.length() >= 16) {
				memcpy(ke1, key.c_str(), 8);
				memcpy(ke2, key.c_str() + 8, 8);
				memcpy(ke3, key.c_str() + 16, key.length() - 16);
			} else if (key.length() >= 8) {
				memcpy(ke1, key.c_str(), 8);
				memcpy(ke2, key.c_str() + 8, key.length() - 8);
				memcpy(ke3, key.c_str(), 8);
			} else {
				memcpy(ke1, key.c_str(), key.length());
				memcpy(ke2, key.c_str(), key.length());
				memcpy(ke3, key.c_str(), key.length());
			}

			DES_key_schedule ks1, ks2, ks3;
			DES_set_key_unchecked(&ke1, &ks1);
			DES_set_key_unchecked(&ke2, &ks2);
			DES_set_key_unchecked(&ke3, &ks3);

			const_DES_cblock inputText;
			DES_cblock outputText;
			vector<unsigned char> vecCleartext;
			unsigned char tmp[8];

			for (int i = 0; i < ciphertext.length() / 8; i ++) {
				memcpy(inputText, ciphertext.c_str() + i * 8, 8);
				DES_ecb3_encrypt(&inputText, &outputText, &ks1, &ks2, &ks3, DES_DECRYPT);
				memcpy(tmp, outputText, 8);

				for (int j = 0; j < 8; j++)
					vecCleartext.push_back(tmp[j]);
			}

			if (ciphertext.length() % 8 != 0) {
				int tmp1 = ciphertext.length() / 8 * 8;
				int tmp2 = ciphertext.length() - tmp1;
				memset(inputText, 0, 8);
				memcpy(inputText, ciphertext.c_str() + tmp1, tmp2);

				DES_ecb3_encrypt(&inputText, &outputText, &ks1, &ks2, &ks3, DES_DECRYPT);
				memcpy(tmp, outputText, 8);

				for (int j = 0; j < 8; j++)
					vecCleartext.push_back(tmp[j]);
			}

			strClearText.clear();
			strClearText.assign(vecCleartext.begin(), vecCleartext.end());
		}
		break;
	case TRIPLE_CBC:
		{
			DES_cblock ke1, ke2, ke3, ivec;
			memset(ke1, 0, 8);
			memset(ke2, 0, 8);
			memset(ke2, 0, 8);

			if (key.length() >= 24) {
				memcpy(ke1, key.c_str(), 8);
				memcpy(ke2, key.c_str() + 8, 8);
				memcpy(ke3, key.c_str() + 16, 8);
			} else if (key.length() >= 16) {
				memcpy(ke1, key.c_str(), 8);
				memcpy(ke2, key.c_str() + 8, 8);
				memcpy(ke3, key.c_str() + 16, key.length() - 16);
			} else if (key.length() >= 8) {
				memcpy(ke1, key.c_str(), 8);
				memcpy(ke2, key.c_str() + 8, key.length() - 8);
				memcpy(ke3, key.c_str(), 8);
			} else {
				memcpy(ke1, key.c_str(), key.length());
				memcpy(ke2, key.c_str(), key.length());
				memcpy(ke3, key.c_str(), key.length());
			}

			DES_key_schedule ks1, ks2, ks3;
			DES_set_key_unchecked(&ke1, &ks1);
			DES_set_key_unchecked(&ke2, &ks2);
			DES_set_key_unchecked(&ke3, &ks3);

			memcpy(ivec, cbc_iv, sizeof(cbc_iv));

			int iLength = ciphertext.length() % 8 ? (ciphertext.length() / 8 + 1) * 8 : ciphertext.length();
			unsigned char* tmp = new unsigned char[iLength];
			memset(tmp, 0, iLength);

			DES_ede3_cbc_encrypt((const unsigned char*)ciphertext.c_str(), tmp, ciphertext.length()+1, &ks1, &ks2, &ks3, &ivec, DES_DECRYPT);

			strClearText = (char*)tmp;

			delete [] tmp;
		}
		break;
	}

	return strClearText;
}

3. main.cpp:

#include "stdafx.h"
#include "cryptotest.h"
#include <iostream>
#include <string>

using namespace std;

void test_DES()
{
	string cleartext = "中国北京12345$abcde%[email protected]!!!!";
	string ciphertext = "";
	string key = "beijingchina1234567890ABCDEFGH!!!";

	CRYPTO_MODE mode = TRIPLE_CBC;

	ciphertext = DES_Encrypt(cleartext, key, mode);
	string decrypt = DES_Decrypt(ciphertext, key, mode);

	cout<<"src cleartext: "<<cleartext<<endl;
	cout<<"genarate ciphertext: "<<ciphertext<<endl;
	cout<<"src ciphertext: "<<ciphertext<<endl;
	cout<<"genarate cleartext: "<<decrypt<<endl;

	if (strcmp(cleartext.c_str(), decrypt.c_str()) == 0)
		cout<<"DES crypto ok!!!"<<endl;
	else
		cout<<"DES crypto error!!!"<<endl;
}

int main(int argc, char* argv[])
{
	test_DES();

	cout<<"ok!!!"<<endl;

	return 0;
}
时间: 2024-08-01 22:42:49

OpenSSL中对称加密算法DES常用函数使用举例的相关文章

常用加密算法的Java实现总结(二) ——对称加密算法DES、3DES和AES

常用加密算法的Java实现总结(二) ——对称加密算法DES.3DES和AES 日期:2014/7/6 文:阿蜜果 1.对称加密算法 1.1 定义 对称加密算法是应用较早的加密算法,技术成熟.在对称加密算法中,数据发信方将明文(原始数据)和加密密钥(mi yue)一起经过特殊加密算法处理后,使其变成复杂的加密密文发送出去.收信方收到密文后,若想解读原文,则需要使用加密用过的密钥及相同算法的逆算法对密文进行解密,才能使其恢复成可读明文.在对称加密算法中,使用的密钥只有一个,发收信双方都使用这个密钥

openssl之对称加密算法命令详解

1.对称加密算法概述 openssl的加密算法库提供了丰富的对称加密算法,我们可以通过openssl提供的对称加密算法指令的方式使用,也可以通过调用openssl提供的API的方式使用. openssl的对称加密算法指令主要用来对数据进行加密和解密处理,openssl基本上为所有其支持的对称加密算法都提供了指令的方式的应用,这些应用指令的名字基本上都是以对称加密算法本身的名字加上位数.加密模式或者其他属性组合而成.例如DES算法的CBC模式,其对应的指令就是des-cbc.可以通过命令查看当前版

对称加密算法DES、3DES原理和实现方式

1.对称加密算法 1.1 定义 对称加密算法是应用较早的加密算法,技术成熟.在对称加密算法中,数据发信方将明文(原始数据)和加密密钥(mi yue)一起经过特殊加密算法处理后,使其变成复杂的加密密文发送出去.收信方收到密文后,若想解读原文,则需要使用加密用过的密钥及相同算法的逆算法对密文进行解密,才能使其恢复成可读明文.在对称加密算法中,使用的密钥只有一个,发收信双方都使用这个密钥对数据进行加密和解密,这就要求解密方事先必须知道加密密钥. 1.2 优缺点 优点:算法公开.计算量小.加密速度快.加

Java加密技术(二)对称加密算法DES&amp;AES

接下来我们介绍对称加密算法,最常用的莫过于DES数据加密算法. DES  DES-Data Encryption Standard,即数据加密算法.是IBM公司于1975年研究成功并公开发表的.DES算法的入口参数有三个:Key.Data.Mode.其中Key为8个字节共64位,是DES算法的工作密钥;Data也为8个字节64位,是要被加密或被解密的数据;Mode为DES的工作方式,有两种:加密或解密. DES算法把64位的明文输入块变为64位的密文输出块,它所使用的密钥也是64位. 通过jav

对称加密算法DES、3DES和AES 原理总结(转载)

1.对称加密算法 1.1 定义 对称加密算法是应用较早的加密算法,技术成熟.在对称加密算法中,数据发信方将明文(原始数据)和加密密钥(mi yue)一起经过特殊加密算法处理后,使其变成复杂的加密密文发送出去.收信方收到密文后,若想解读原文,则需要使用加密用过的密钥及相同算法的逆算法对密文进行解密,才能使其恢复成可读明文.在对称加密算法中,使用的密钥只有一个,发收信双方都使用这个密钥对数据进行加密和解密,这就要求解密方事先必须知道加密密钥. 1.2 优缺点 优点:算法公开.计算量小.加密速度快.加

Java加密技术(二)——对称加密算法DES&AES

接下来我们介绍对称加密算法,最常用的莫过于DES数据加密算法. DES DES-Data Encryption Standard,即数据加密算法.是IBM公司于1975年研究成功并公开发表的.DES算法的入口参数有三个:Key.Data.Mode.其中Key为8个字节共64位,是DES算法的工作密钥;Data也为8个字节64位,是要被加密或被解密的数据;Mode为DES的工作方式,有两种:加密或解密. DES算法把64位的明文输入块变为64位的密文输出块,它所使用的密钥也是64位. 通过java

在OpenSSL中添加自定义加密算法

一.简介 本文以添加自定义算法EVP_ssf33为例,介绍在OpenSSL中添加自定义加密算法的方法 二.步骤 1.修改crypto/object/objects.txt,注册算法OID,如下: rsadsi 3 255 : SSF33 : ssf33 2.进入目录:crypto/object/,执行如下命令,生成算法的声明 perl objects.pl objects.txt obj_mac.num obj_mac.h 3.在crypto/evp/下添加e_ssf33.c,内容如下 #inc

对称加密算法:DES加密和DESede加密和AES和PBE

对称加密算法是说加密方和解密方使用相同的密钥.常见的对称加密算法包括4个,DES,DESede(3DES),AES,PBE. 本文讨论的内容是加密算法,不是Message Digest,不是编码.下面区分一下这三个概念. 加密算法是一对一映射,明文密文一一对应.加密是不明确的,是隐晦的. 信息摘要是一个密文对应多个明文,它只是明文整体的一个指纹,一个反映,一个摘要. 编码是一对一映射,是明确的,是显然易见的,比如base64编码. DES(Data Encryption Standard)名叫数

java-信息安全(二)-对称加密算法DES,3DES,AES,Blowfish,RC2,RC4

概述 信息安全基本概念: DES(Data Encryption Standard,数据加密标准) 3DES(Triple DES,三重数据加密算法(TDEA,Triple Data Encryption Algorithm)) AES(Advanced Encryption Standard,高级加密标准) Blowfish RC2 RC4 DES DES全称为Data Encryption Standard,即数据加密标准,是一种使用密钥加密的块算法,1977年被美国联邦政府的国家标准局确定