C++利用Crypto++,vs2005环境下的RSA应用
2015-07-24 15:02
567 查看
——————————————————说明:部分内容参考网上现有。————————————————--
——————此文适合新手入门,大神直接飞过————————
————感想,可跳过哈 ,^_^————
这几天老师要求做一个关于rsa加密的项目,要求加解密文本内容。主要遇到密钥生成、待加解密字符串过长等遇到问题,下面会一一解决。网上查看资料大多是每次都生成新的密钥,而且加密的明文较短,所以第一次有了写博客的冲动哈!~~~~~
—————进入主题 ! ———————
一、crypto++sdk,环境及项目的配置,参照:http://www.cnblogs.com/cxun/archive/2008/07/30/743541.html
二、生成固定密钥,参照crypto++官方文档:http://www.cryptopp.com/wiki/Keys_and_Formats#Generating.2C_Validating.2C_Saving.2C_and_Loading_Keys
所用代码示例也为官方sample,稍稍改动了一点点,在代码中会有说明。(别被吓唬了,其实慢慢看还是很容易的)
必须现在c盘建一个rsa05的文件夹,否则会出错。出错点在下面代码中有标注。(之前没有建立这个文件夹,程序会中断抛出异常。)
三、下面是我根据官方的说明自己做了两个函数用于加解密任意长度的字符串。下面在代码里讲解。
——————rsajm.h——————
四、最后贴出网上看到把txt文件内容到string里面的非常精简的代码段
五、OK~~~~~~~处女座~~~~~~~~~
——————此文适合新手入门,大神直接飞过————————
————感想,可跳过哈 ,^_^————
这几天老师要求做一个关于rsa加密的项目,要求加解密文本内容。主要遇到密钥生成、待加解密字符串过长等遇到问题,下面会一一解决。网上查看资料大多是每次都生成新的密钥,而且加密的明文较短,所以第一次有了写博客的冲动哈!~~~~~
—————进入主题 ! ———————
一、crypto++sdk,环境及项目的配置,参照:http://www.cnblogs.com/cxun/archive/2008/07/30/743541.html
二、生成固定密钥,参照crypto++官方文档:http://www.cryptopp.com/wiki/Keys_and_Formats#Generating.2C_Validating.2C_Saving.2C_and_Loading_Keys
所用代码示例也为官方sample,稍稍改动了一点点,在代码中会有说明。(别被吓唬了,其实慢慢看还是很容易的)
必须现在c盘建一个rsa05的文件夹,否则会出错。出错点在下面代码中有标注。(之前没有建立这个文件夹,程序会中断抛出异常。)
#include <iostream> using std::cout; using std::cerr; using std::endl; #include <string> using std::string; #include <stdexcept> using std::runtime_error; #include <queue.h> using CryptoPP::ByteQueue; #include "filters.h" using CryptoPP::StringSink; using CryptoPP::StringSource; using CryptoPP::PK_EncryptorFilter; using CryptoPP::PK_DecryptorFilter; #include <files.h> using CryptoPP::FileSource; using CryptoPP::FileSink; #include "dsa.h" using CryptoPP::DSA; #include "rsa.h" using CryptoPP::RSA; using CryptoPP::InvertibleRSAFunction; using CryptoPP::RSAES_OAEP_SHA_Encryptor; using CryptoPP::RSAES_OAEP_SHA_Decryptor; #include <cryptlib.h> using CryptoPP::PrivateKey; using CryptoPP::PublicKey; using CryptoPP::BufferedTransformation; #include "osrng.h" using CryptoPP::AutoSeededRandomPool; #pragma comment(lib, "cryptlib.lib"); void EncodePrivateKey(const string& filename, const RSA::PrivateKey& key); void EncodePublicKey(const string& filename, const RSA::PublicKey& key); void Encode(const string& filename, const BufferedTransformation& bt); void DecodePrivateKey(const string& filename, RSA::PrivateKey& key); void DecodePublicKey(const string& filename, RSA::PublicKey& key); void Decode(const string& filename, BufferedTransformation& bt); int main(int argc, char** argv) { std::ios_base::sync_with_stdio(false); // http://www.cryptopp.com/docs/ref/class_auto_seeded_random_pool.html AutoSeededRandomPool rnd; // http://www.cryptopp.com/docs/ref/rsa_8h.html RSA::PrivateKey rsaPrivate; rsaPrivate.GenerateRandomWithKeySize(rnd, 2048); RSA::PublicKey rsaPublic(rsaPrivate); EncodePrivateKey("C:\\rsa05\\rsa-private.key", rsaPrivate); //将密钥放在C:\\rsa05目录下 EncodePublicKey("C:\\rsa05\\rsa-public.key", rsaPublic); //必须预先在C盘建立rsa05文件夹,否则出错 cout << "Successfully generated and saved RSA keys" << endl; //////////////////////////////////////////////////////////////////////////////////// RSA::PrivateKey k1; DecodePrivateKey("C:\\rsa05\\rsa-private.key", k1); RSA::PublicKey k2; DecodePublicKey("C:\\rsa05\\rsa-public.key", k2); cout << "Successfully loaded RSA keys" << endl; //////////////////////////////////////////////////////////////////////////////////// if(!k1.Validate(rnd, 3)) throw runtime_error("Rsa private key validation failed"); if(!k2.Validate(rnd, 3)) throw runtime_error("Rsa public key validation failed"); cout << "Successfully validated RSA keys" << endl; //////////////////////////////////////////////////////////////////////////////////// if(rsaPrivate.GetModulus() != k1.GetModulus() || rsaPrivate.GetPublicExponent() != k1.GetPublicExponent() || rsaPrivate.GetPrivateExponent() != k1.GetPrivateExponent()) { throw runtime_error("private key data did not round trip"); } if(rsaPublic.GetModulus() != k2.GetModulus() || rsaPublic.GetPublicExponent() != k2.GetPublicExponent()) { throw runtime_error("public key data did not round trip"); } cout << "Successfully round-tripped RSA keys" << endl; //////////////////////////////////////////////////////////////////////////////////// //其实这里就可以实现简单的加解密了 //------------------------------------------------------------------------------- /* string plain="RSA Encryption", cipher, recovered; //////////////////////////////////////////////// // Encryption RSAES_OAEP_SHA_Encryptor e( k2 ); StringSource( plain, true, new PK_EncryptorFilter( rnd, e, new StringSink( cipher ) ) // PK_EncryptorFilter ); // StringSource //////////////////////////////////////////////// //////////////////////////////////////////////// //////////////////////////////////////////////// // Decryption RSAES_OAEP_SHA_Decryptor d( k1 ); StringSource( cipher, true, new PK_DecryptorFilter( rnd, d, new StringSink( recovered ) ) // PK_EncryptorFilter ); // StringSource assert( plain == recovered ); cout<<"plain:\t"<<plain<<"\r\n\r\n"<<"cipher:\t"<<cipher<<"\r\n\r\n"; */ //------------------------------------------------------------------------------- return 0; } void EncodePrivateKey(const string& filename, const RSA::PrivateKey& key) { // http://www.cryptopp.com/docs/ref/class_byte_queue.html ByteQueue queue; key.DEREncodePrivateKey(queue); Encode(filename, queue); } void EncodePublicKey(const string& filename, const RSA::PublicKey& key) { // http://www.cryptopp.com/docs/ref/class_byte_queue.html ByteQueue queue; key.DEREncodePublicKey(queue); Encode(filename, queue); } void Encode(const string& filename, const BufferedTransformation& bt) { // http://www.cryptopp.com/docs/ref/class_file_sink.html FileSink file(filename.c_str()); bt.CopyTo(file); file.MessageEnd(); } void DecodePrivateKey(const string& filename, RSA::PrivateKey& key) { // http://www.cryptopp.com/docs/ref/class_byte_queue.html ByteQueue queue; Decode(filename, queue); key.BERDecodePrivateKey(queue, false /*optParams*/, queue.MaxRetrievable()); } void DecodePublicKey(const string& filename, RSA::PublicKey& key) { // http://www.cryptopp.com/docs/ref/class_byte_queue.html ByteQueue queue; Decode(filename, queue); key.BERDecodePublicKey(queue, false /*optParams*/, queue.MaxRetrievable()); } void Decode(const string& filename, BufferedTransformation& bt) { // http://www.cryptopp.com/docs/ref/class_file_source.html FileSource file(filename.c_str(), true /*pumpAll*/); file.TransferTo(bt); bt.MessageEnd(); }
三、下面是我根据官方的说明自己做了两个函数用于加解密任意长度的字符串。下面在代码里讲解。
——————rsajm.h——————
#include "randpool.h" #include "dsa.h" #include "rsa.h" #include "osrng.h" #include "hex.h" #include "filters.h" #include "files.h" #include "cryptlib.h" #include <string.h> #include <iostream> #include <queue.h> using namespace std; using namespace CryptoPP; #pragma comment(lib, "cryptlib.lib") void EncodePrivateKey(const string& filename, const RSA::PrivateKey& key); void EncodePublicKey(const string& filename, const RSA::PublicKey& key); void Encode(const string& filename, const BufferedTransformation& bt); void DecodePrivateKey(const string& filename, RSA::PrivateKey& key); void DecodePublicKey(const string& filename, RSA::PublicKey& key); void Decode(const string& filename, BufferedTransformation& bt); void EncodePrivateKey(const string& filename, const RSA::PrivateKey& key) { // http://www.cryptopp.com/docs/ref/class_byte_queue.html ByteQueue queue; key.DEREncodePrivateKey(queue); Encode(filename, queue); } void EncodePublicKey(const string& filename, const RSA::PublicKey& key) { // http://www.cryptopp.com/docs/ref/class_byte_queue.html ByteQueue queue; key.DEREncodePublicKey(queue); Encode(filename, queue); } void Encode(const string& filename, const BufferedTransformation& bt) { // http://www.cryptopp.com/docs/ref/class_file_sink.html FileSink file(filename.c_str()); bt.CopyTo(file); file.MessageEnd(); } void DecodePrivateKey(const string& filename, RSA::PrivateKey& key) { // http://www.cryptopp.com/docs/ref/class_byte_queue.html ByteQueue queue; Decode(filename, queue); key.BERDecodePrivateKey(queue, false /*optParams*/, queue.MaxRetrievable()); } void DecodePublicKey(const string& filename, RSA::PublicKey& key) { // http://www.cryptopp.com/docs/ref/class_byte_queue.html ByteQueue queue; Decode(filename, queue); key.BERDecodePublicKey(queue, false /*optParams*/, queue.MaxRetrievable()); } void Decode(const string& filename, BufferedTransformation& bt) { // http://www.cryptopp.com/docs/ref/class_file_source.html FileSource file(filename.c_str(), true /*pumpAll*/); file.TransferTo(bt); bt.MessageEnd(); } <pre name="code" class="cpp">AutoSeededRandomPool rnd; //接收string类型字符串,进行rsa加密,并进行16进制编码,最后返回密文。 // string myRsaEncrypt(string myPlaintText) { RSA::PublicKey myPubkey; DecodePublicKey("C:\\rsa05\\rsa-public.key", myPubkey); RSAES_OAEP_SHA_Encryptor e( myPubkey ); string result; //—————————————————————————————————————————————————————— //由于加密的明文有最大长度,长度为FixedMaxPlaintextLength(),所以下面进行字符串长度的分割。 int maxTextlen = e.FixedMaxPlaintextLength(); for ( int i = myPlaintText.size() , j = 0; i > 0; i -= maxTextlen , j += maxTextlen) { string partPlaintext = myPlaintText.substr(j,maxTextlen); string partCiphertext ; StringSource(partPlaintext, true, new PK_EncryptorFilter(rnd, e, new HexEncoder(new StringSink(partCiphertext)))); result += partCiphertext ; } return result; } //解密函数和上面的加密函数差不多哈~~ string myRsaDecrypt(string myCipherText) { RSA::PrivateKey myPrikey; DecodePrivateKey("C:\\rsa05\\rsa-private.key", myPrikey); RSAES_OAEP_SHA_Decryptor d( myPrikey ); string result; int maxCiphertextLen = d.FixedCiphertextLength() * 2; for ( int i = myCipherText.size() , j = 0; i > 0; i -= maxCiphertextLen , j += maxCiphertextLen) { string partCiphertext= myCipherText.substr(j,maxCiphertextLen); string partPlaintext ; StringSource(partCiphertext, true, new HexDecoder(new PK_DecryptorFilter(rnd, d, new StringSink(partPlaintext)))); result += partPlaintext ; } return result; }
四、最后贴出网上看到把txt文件内容到string里面的非常精简的代码段
ifstream in("C:\\rsa05\\resultCipher.txt", ios::in); istreambuf_iterator<char> beg(in), end; string sResultData(beg, end); in.close(); // cout<<sResultData;
五、OK~~~~~~~处女座~~~~~~~~~
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- OpenSSL编程之RSA
- 关于指针的一些事情
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- Lua中调用C++函数示例
- Lua教程(一):在C++中嵌入Lua脚本
- Lua教程(二):C++和Lua相互传递数据示例
- C++联合体转换成C#结构的实现方法
- C++编写简单的打靶游戏
- C++ 自定义控件的移植问题
- C++变位词问题分析
- C/C++数据对齐详细解析
- C++基于栈实现铁轨问题
- C++中引用的使用总结
- 使用Lua来扩展C++程序的方法
- C++中调用Lua函数实例
- Lua和C++的通信流程代码实例
- C与C++之间相互调用实例方法讲解
- C++ Custom Control控件向父窗体发送对应的消息