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

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

MyRSA.h头文件如下:

/*
 * 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 源文件如下:

/*
 * 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系统下,编译命令于上一节差不多

g++ MyRSA.cpp -o rsa -lpthread -lcryptopp

 

转载于:https://my.oschina.net/u/566591/blog/168520

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值