抽了点时间研究了下 crypto++ 这个开源库,不过发现其文档极其缺乏,果然是代码即文档……
原以为上手会极其迅速,但是过程中还是遇到了一些问题。现在把它记录下来。
cryptopp 官方说明的是支持多平台的,我也就没多想从官网下了个5.60,下载下来的zip包里面又包含vc的工程文件,又包含makefile
郁闷的是makefile 里默认只生成静态库,而想要在linux 下正常运行 还需要生成.so的动态库。
1、修改下官方自带的 GUNmakefile 修改部分如下
install:
$(MKDIR) -p $(PREFIX)/include/cryptopp $(PREFIX)/lib $(PREFIX)/bin
$(CP) *.h $(PREFIX)/include/cryptopp
$(CP) *.a $(PREFIX)/lib
$(CP) *.so $(PREFIX)/lib
$(CP) *.exe $(PREFIX)/bin
libcryptopp.a: $(LIBOBJS)
$(AR) $(ARFLAGS) $@ $(LIBOBJS)
$(RANLIB) $@
libcryptopp.so: $(LIBOBJS)
$(CXX) -shared -o $@ $(LIBOBJS)
cryptest.exe: libcryptopp.a $(TESTOBJS)
$(CXX) -o $@ $(CXXFLAGS) $(TESTOBJS) -L. -lcryptopp $(LDFLAGS) $(LDLIBS)
比对一下官网的makefile 把该加的加进去
如果是64位机器 记得去掉# CXXFLAGS += -fPIC 这一行的注释,编译时要加上-fPIC 这个选项
2、运行
make
make libcryptopp.so
make install
OK 如果没什么错误提示的话,那么这个库就算是编译安装完成了
3、示例程序
/*
* cryptopp_rsa_test.cc
*/
#include <cryptopp/randpool.h>
#include <cryptopp/rsa.h>
#include <cryptopp/hex.h>
#include <cryptopp/files.h>
#include <iostream>
using namespace std;
using namespace CryptoPP;
#pragma comment(lib, "cryptlib.lib")
//------------------------
// 函数声明
//------------------------
void GenerateRSAKey(unsigned int keyLength, const char *privFilename, const char *pubFilename, const char *seed);
string RSAEncryptString(const char *pubFilename, const char *seed, const char *message);
string RSADecryptString(const char *privFilename, const char *ciphertext);
RandomPool & GlobalRNG();
//------------------------
// 主程序
//------------------------
int main()
{
char priKey[128] = {0};
char pubKey[128] = {0};
char seed[1024] = {0};
// 生成 RSA 密钥对
strcpy(priKey, "pri"); // 生成的私钥文件
strcpy(pubKey, "pub"); // 生成的公钥文件
strcpy(seed, "seed");
GenerateRSAKey(1024, priKey, pubKey, seed);
//RSA 加解密
char message[1024] = {0};
cout<<"Origin Text:\t"<<"just a test!"<<endl<<endl;
strcpy(message, "just a test!");
string encryptedText = RSAEncryptString(pubKey, seed, message); // RSA 加密
cout<<"Encrypted Text:\t"<<encryptedText<<endl<<endl;
string decryptedText = RSADecryptString(priKey, encryptedText.c_str()); // RSA 解密
cout<<"Decrypted Text:\t"<<decryptedText<<endl<<endl;
return 0;
}
//------------------------
//生成 RSA 密钥对
//------------------------
void GenerateRSAKey(unsigned int keyLength, const char *privFilename, const char *pubFilename, const char *seed)
{
RandomPool randPool;
randPool.Put((byte *)seed, strlen(seed));
RSAES_OAEP_SHA_Decryptor priv(randPool, 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();
}
//------------------------
// RSA 加密
//------------------------
string RSAEncryptString(const char *pubFilename, const char *seed, const char *message)
{
FileSource pubFile(pubFilename, true, new HexDecoder);
RSAES_OAEP_SHA_Encryptor pub(pubFile);
RandomPool randPool;
randPool.Put((byte *)seed, strlen(seed));
string result;
StringSource(message, true, new PK_EncryptorFilter(randPool, pub, new HexEncoder(new StringSink(result))));
return result;
}
//------------------------
// RSA 解密
//------------------------
string RSADecryptString(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(GlobalRNG(), priv, new StringSink(result))));
return result;
}
//------------------------
// 定义全局的随机数池
//------------------------
RandomPool & GlobalRNG()
{
static RandomPool randomPool;
return randomPool;
}
4、编译时记得用
g++ -lcryptopp -lpthread Cryptopp_test.cc -o Cryptopp_test
运行下 ./Cryptopp_test 应该会看到
Origin Text: just a test!
Encrypted Text: 50B1F49740A7AF7093A66BC5608DA43098ECC0C6EBE09D062C486A7151A5270BFE29098516E3DEE957410075010DD6DF0500A561BECA1F765A55BF4D8D6CD4A2CB165EA1EE24F36BE920A1A39C57A0ECEB708B5CFE477515579C0B28D9756DA79A9497573610BEE03D0514B9F2F693E9E44478B6E117A15D3F6F56801E8521E3
Decrypted Text: just a test!