前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >利用Crypto++实现RSA加密算法

利用Crypto++实现RSA加密算法

作者头像
一灰灰blog
发布2018-02-06 12:02:04
2.4K0
发布2018-02-06 12:02:04
举报
文章被收录于专栏:小灰灰小灰灰

之前做一个项目用到crypto++加密库,可以从官网下载对应的源码,其中有一个test.c文件,详细的演示了各种加密算法的使用方法,因此,在其基础上,我将aes、rsa、MD5进行了简单的封装,以便于更好的使用

MyRSA.h头文件如下:

代码语言:javascript
复制
/*
 * MyRSA.h
 *
 *  Created on: 2013-3-7
 *      Author: wzb
 */

#ifndef MYRSA_H_
#define MYRSA_H_

#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1
#include <iostream>
#include <string>

#include <cryptopp/rsa.h>
#include <cryptopp/hex.h>
#include <cryptopp/osrng.h>
#include <cryptopp/files.h>
#include <cryptopp/md5.h>

using namespace std;
using namespace CryptoPP;

class MyRSA
{
public:
	MyRSA();
	~MyRSA();

	string MD5(const char * message);
	string MD5File(const char * filename);

	void GenerateRSAKey(unsigned int keyLength, const char *privFilename,
			const char *pubFilename);

	string Encrypt(const char * pubFilename, const char * message);
	string Decrypt(const char * privFilename, const char * cipher);

	void SignFile(const char * privFilename, const char * messageFilename,
			const char * signatureFilename);
	bool VerifyFile(const char *pubFilename, const char * messageFilename,
			const char * signatureFilename);

	SecByteBlock SignString(const char *privFilename, const char * message);
	bool VerifyString(const char * pubFilename, const char * messsage,
			const SecByteBlock &SecByteBlock);
private:
	AutoSeededRandomPool _rng;
};

#endif /* MYRSA_H_ */

MyRSA.cpp 源文件如下:

代码语言:javascript
复制
/*
 * MyRSA.cpp
 *
 *  Created on: 2013-3-7
 *      Author: hust
 */
#include "MyRSA.h"
#include <time.h>
MyRSA::MyRSA()
{

}

MyRSA::~MyRSA()
{

}
/*
 * Description: this function is used to calcuate the string 'message' 's hash value
 * Input:
 * 	message: the init string to be hashed
 * Output:
 * 	return the hash of the parameter
 */
string MyRSA::MD5(const char * message)
{
	string digest;
	Weak::MD5 md5;
	StringSource(message, true,
			new HashFilter(md5, new HexEncoder(new StringSink(digest))));
	return digest;
}
/*
 * Description: to calculate the hash of the file and return the hash value(string)
 * Input:
 * 	filename: the file to be calculated the hash value
 * Output:
 *  return the hash value of the file and its type is string
 */
string MyRSA::MD5File(const char * filename)
{
	string digest;
	Weak::MD5 md5;
	FileSource(filename, true,
			new HashFilter(md5, new HexEncoder(new StringSink(digest))));
	return digest;

}

/*
 * Description: generate the RSA public key and private key in separate file
 * Input:
 *  KeyLength: the length of the key, such as 1024...
 *  privFilename: private key file name you want to store the private key
 *  pubFilename: public key file name you want to store the public key
 * Output:
 * 	nothing
 */
void MyRSA::GenerateRSAKey(unsigned int keyLength, const char *privFilename,
		const char *pubFilename)
{
	RSAES_OAEP_SHA_Decryptor priv(_rng, keyLength);
	HexEncoder privFile(new FileSink(privFilename));
	priv.DEREncode(privFile);
	privFile.MessageEnd();

	RSAES_OAEP_SHA_Encryptor pub(priv);
	HexEncoder pubFile(new FileSink(pubFilename));
	pub.DEREncode(pubFile);
	pubFile.MessageEnd();
}

/*
 * Description: this function is used to encrypt the string 'plainText' with the
 * 				private key, and return the cipher
 * Input:
 * 	pubFilename: the public key
 * 	message: the string to be encrypted
 * OutPut:
 *  return the cipher
 */
string MyRSA::Encrypt(const char * pubFilename, const char * message)
{
	FileSource pubFile(pubFilename, true, new HexDecoder);

	RSAES_OAEP_SHA_Encryptor pub(pubFile);
	string result;
	StringSource(message, true,
			new PK_EncryptorFilter(_rng, pub,
					new HexEncoder(new StringSink(result))));
	return result;
}
/*
 * Description: decrypt the cipher with the private key
 * Input:
 * 	privFilename: the private key file
 * 	ciphertext: the string to be decrypted
 * Output:
 * 	return the decrypted string
 */
string MyRSA::Decrypt(const char * privFilename, const char * ciphertext)
{
	FileSource privFile(privFilename, true, new HexDecoder);

	RSAES_OAEP_SHA_Decryptor priv(privFile);
	string result;
	StringSource(ciphertext, true,
			new HexDecoder(
					new PK_DecryptorFilter(_rng, priv,
							new StringSink(result))));
	return result;
}

/*
 * Description: sign the file with the private key, and generate the signature file
 * Input:
 *  privFilename: the private key file
 *  messageFilename: the file to be signed
 *  signatureFilename: the signature file to be generated
 * Output:
 * 	nothing
 */
void MyRSA::SignFile(const char * privFilename, const char *messageFilename,
		const char * signatureFilename)
{
	FileSource priFile(privFilename, true, new HexDecoder);
	RSASS<PKCS1v15, SHA>::Signer priv(priFile);
	FileSource f(messageFilename, true,
			new SignerFilter(_rng, priv,
					new HexEncoder(new FileSink(signatureFilename))));
}

/*
 * Description: verify the file with the public key, and return the answer
 * Input:
 *  pubFilename: the publicFilename
 *  messageFilename: the init message file, and it should be not changed
 *  signatureFilename: the SignFile function generate, and it's used to verify if the message
 *  					file is the original one
 * Output:
 * 	if the message file match the signature file, return true; else return false
 */
bool MyRSA::VerifyFile(const char * pubFilename, const char * messageFilename,
		const char * signatureFilename)
{
	FileSource pubFile(pubFilename, true, new HexDecoder);
	RSASS<PKCS1v15, SHA>::Verifier pub(pubFile);

	FileSource signatureFile(signatureFilename, true, new HexDecoder);
	if (signatureFile.MaxRetrievable() != pub.SignatureLength())
		return false;
	SecByteBlock signature(pub.SignatureLength());
	signatureFile.Get(signature, signature.size());

	VerifierFilter *verifierFilter = new VerifierFilter(pub);
	verifierFilter->Put(signature, pub.SignatureLength());
	FileSource f(messageFilename, true, verifierFilter);

	return verifierFilter->GetLastResult();
}

/*
 * Description: sign the string with the private key, and generate the signature
 * Input:
 *  privFilename: the private key file
 *  message: the string to be signed
 * Output:
 * 	return the SecByteBlock signature
 */
SecByteBlock MyRSA::SignString(const char * privFilename, const char * message)
{
	// calculate the md5(HASH) of the message
	string digest = MD5(message);
	FileSource priFile(privFilename, true, new HexDecoder);
	RSASSA_PKCS1v15_SHA_Signer priv(priFile);

	// Create signature space
	size_t length = priv.MaxSignatureLength();
	SecByteBlock signature(length);

	// sign message
	priv.SignMessage(_rng, (const byte*) digest.c_str(), digest.length(),
			signature);

	return signature;
}
/*
 * Description: verify the file with the public key, and return the answer
 * Input:
 *  pubFilename: the publicFilename
 *  message: the original message, and it should be not changed
 *  signature: the SignString function returned, and it's used to verify if the message
 *  		   is the original one
 * Output:
 * 	if the message match the signature , return true; else return false
 */
bool MyRSA::VerifyString(const char * pubFilename, const char * message,
		const SecByteBlock & signature)
{
	// calculate the md5 of the message first
	string digest = MD5(message);
	FileSource pubFile(pubFilename, true, new HexDecoder);
	RSASSA_PKCS1v15_SHA_Verifier verifier(pubFile);

	bool result = verifier.VerifyMessage((const byte*) digest.c_str(),
			digest.length(), signature, signature.size());
	return result;
}


 int main() {
 char privFilename[128] = "prvKey", pubFilename[128] = "pubKey";
 unsigned int keyLength = 1024;
 clock_t start, finish;
 double duration;


 //	cout << "Key length in bits: ";
 //	cin >> keyLength;

 //	cout << "\nSave private key to file: ";
 //	cin >> privFilename;

 //	cout << "\nSave public key to file: ";
 //	cin >> pubFilename;


 MyRSA rsa;


 start = clock();
 cout << "============encrypt and decrypt================" << endl;
 rsa.GenerateRSAKey(keyLength, privFilename, pubFilename);
 string message = "hello world, i am a student from huazhong university of science and technology!";
 string ciphertext = rsa.Encrypt(pubFilename, message.c_str());
 cout << "The cipher is : " << ciphertext << endl;

 string decrypted = rsa.Decrypt(privFilename, ciphertext.c_str());
 cout << "The recover is : " << decrypted << endl;

 finish = clock();
 duration = (double) (finish - start) / CLOCKS_PER_SEC;
 cout << "The cost is : " << duration << " seconds" << endl;


 cout << "==============sign file================" << endl;
 start = clock();
 string messageFilename = "signTest";
 string signatureFilename = "signature";
 rsa.SignFile(privFilename, messageFilename.c_str(),
 signatureFilename.c_str());

 if (rsa.VerifyFile(pubFilename, messageFilename.c_str(),
 signatureFilename.c_str())) {
 cout << "verify correct!" << endl;
 } else
 cout << "verify error!" << endl;

 finish = clock();
 duration = (double) (finish - start) / CLOCKS_PER_SEC;
 cout << "The sign file cost is : " << duration << " seconds" << endl;


 cout << "============sign string=================" << endl;
 start = clock();
 string plainText = "Sign me, i am a student from huazhong university of science and technology!";

 SecByteBlock signature = rsa.SignString(privFilename, plainText.c_str());
 cout << "The Signature size is : " << signature.size() << endl;

 //cout << endl << "The signature is : " << signature << endl << endl;

 // save the signature to the file
 //ofstream signatureFile("signatureFile");
 //if(signatureFile.is_open() )
 //{
 //	for(int i = 0; i < signature.get
 //}

 if (rsa.VerifyString(pubFilename, plainText.c_str(), signature)) {
 cout << "Verify correct!" << endl;
 } else {
 cout << "Verify wrong!" << endl;
 }

 finish = clock();
 duration = (double) (finish - start) / CLOCKS_PER_SEC;
 cout << "The sign string cost is : " << duration << " seconds" << endl;
 return 0;
 }

在linux系统下,编译命令于上一节差不多

代码语言:javascript
复制
g++ MyRSA.cpp -o rsa -lpthread -lcryptopp
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档