之前做一个项目用到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