Crypto移植笔记
2018.06.12 许静
1. 环境: vs2017, crypto7.0
2. 修改代码,使编译通过。测试crylib项目。
无法打开源文件stdio.h, stddef.h,stdlib.h等文件, 在包含目录中添加:
C:\Program Files(x86)\Windows Kits\10\Include\10.0.16299.0\ucrt
注意10.0.16299.0版本是否存在本机目录下。
“找不到Windows SDK版本8.1. 请安装所需的版本的Windows SDK或者在项目属性页中或通过右键单击解决方案并选择“重定解决方案目标”来更改SDK版本”。更改一下,不出现错误。
3. 添加cryptlib.lib和所有.h文件。
4. 属性->c/c++->代码生成->运行库 多线程调试。
出错。
#error指令:Please use the /MD switch for _AFXDLL builds.
原因:将MFC设置成在共享dll中使用MFC.
解决方案:属性->常规->MFC的使用->在静态库中使用MFC.
5. 源文件
#ifndef __RSA_MAIN_H__
#define __RSA_MAIN_H__
#include <iostream>
#include <string>
#define _GEN_RSA 1
#if !_GEN_RSA
#define _SPE_RSA 1
#endif
class RSA_C {
public:
RSA_C(void);
~RSA_C(void);
std::string PubEn(const char* message);
std::string PriDe(const char* chiphtertext);
void GenerateRSAKey(unsigned int keyLength, const char *privFilename, const char *pubFilename, const char *seed);
private:
unsigned int keyLen;
char *privFilename;
char *pubFilename;
char *seed;
/*
#if _SPE_RSA
RSA::PrivateKey k1;
RSA::PublicKey k2;
AutoSeededRandomPool rnd;
#endif
*/
};
extern RSA_C g_RSA_App;
#endif
- #include "RSA_main.h"
- #include "rsa.h"
- #include "randpool.h"
- #include "hex.h"
- #include "files.h"
- #include "cryptlib.h"
- #include "queue.h"
- #include "filters.h"
- #include "osrng.h"
- #include <stdexcept>
- using std::runtime_error;
- using namespace CryptoPP;
- #pragma comment(lib, "cryptlib.lib")
- RSA_C g_RSA_App;
- #if _GEN_RSA
- static std::string RSADecryptString(const char *privFilename, const char *ciphertext);
- static std::string RSAEncryptString(const char *pubFilename, const char *seed, const char *message);
- static RandomPool& GlobalRNG(void);
- void Encode(const std::string& filename, const BufferedTransformation& bt);
- #endif
- #if _SPE_RSA
- void Encode(const std::string& filename, const BufferedTransformation& bt);
- void Decode(const std::string& filename, BufferedTransformation& bt);
- #endif
- #if _SPE_RSA
- RSA::PrivateKey k1;
- RSA::PublicKey k2;
- AutoSeededRandomPool rnd;
- #endif
- RSA_C::RSA_C(void)
- {
- privFilename = new char[1024];
- pubFilename = new char[1024];
- seed = new char[1024];
- }
- RSA_C::~RSA_C()
- {
- delete privFilename;
- delete pubFilename;
- delete seed;
- }
- std::string RSA_C::PubEn(const char* message)
- {
- std::string enText = "";
- #if _GEN_RSA
- std::cout << "origin text:" << message << '\n';
- enText = RSAEncryptString(pubFilename, seed, message);
- std::cout << "Encrypted Text:" << enText << '\n';
- #endif
- #if _SPE_RSA
- RSAES_OAEP_SHA_Encryptor e(k2);
- StringSource(message, true, new PK_EncryptorFilter(rnd,e, new StringSink(enText)));
- #endif
- return enText;
- }
- std::string RSA_C::PriDe(const char* chiphtertext)
- {
- std::string deText = "";
- #if _GEN_RSA
- std::cout << "Encryped text:" << chiphtertext << '\n';
- deText = RSADecryptString(privFilename, chiphtertext);
- std::cout << "Decrypted Text:" << deText << '\n';
- #endif
- #if _SPE_RSA
- RSAES_OAEP_SHA_Decryptor d(k1);
- StringSource(chiphtertext, true, new PK_DecryptorFilter(rnd, d, new StringSink(deText)));
- #endif
- return deText;
- }
- #if _GEN_RSA
- static RandomPool& GlobalRNG(void)
- {
- static RandomPool randomPool;
- return randomPool;
- }
- #endif
- #if _SPE_RSA
- void EncodePrivateKey(const std::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 std::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 std::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 std::string& filename, RSA::PrivateKey& key)
- {
- ByteQueue queue;
- Decode(filename, queue);
- key.BERDecodePrivateKey(queue, false, queue.MaxRetrievable());
- }
- void DecodePublickey(const std::string& filename, RSA::PublicKey& key)
- {
- ByteQueue queue;
- Decode(filename, queue);
- key.BERDecodePublicKey(queue, false, queue.MaxRetrievable());
- }
- void Decode(const std::string& filename, BufferedTransformation& bt)
- {
- FileSource file(filename.c_str(), true);
- file.TransferTo(bt);
- bt.MessageEnd();
- }
- #endif
- void RSA_C::GenerateRSAKey(unsigned int ikeyLength, const char *iprivFilename, const char *ipubFilename, const char *iseed)
- {
- #if _GEN_RSA
- keyLen = ikeyLength;
- strcpy(privFilename, iprivFilename);
- strcpy(pubFilename, ipubFilename);
- strcpy(seed, iseed);
- // DEREncode() changed to Save() at Issue 569.
- RandomPool randPool;
- randPool.IncorporateEntropy((byte *)iseed, strlen(seed));
- RSAES_OAEP_SHA_Decryptor priv(randPool, ikeyLength);
- HexEncoder privFile(new FileSink(iprivFilename));
- priv.AccessMaterial().Save(privFile);
- privFile.MessageEnd();
- RSAES_OAEP_SHA_Encryptor pub(priv);
- HexEncoder pubFile(new FileSink(ipubFilename));
- pub.AccessMaterial().Save(pubFile);
- pubFile.MessageEnd();
- #endif
- #if _SPE_RSA
- AutoSeededRandomPool rnd;
- RSA::PrivateKey rsaPrivate;
- rsaPrivate.GenerateRandomWithKeySize(rnd, 2048);
- RSA::PublicKey rsaPublic(rsaPrivate);
- // generate
- EncodePrivateKey("C:\\rsa05\\rsa-private.key", rsaPrivate); //将密钥放在C:\\rsa05目录下
- EncodePublicKey("C:\\rsa05\\rsa-public.key", rsaPublic); //必须预先在C盘建立rsa05文件夹,否则出错
- std::cout << "Successfully generated and saved RSA keys" << '\n';
- //load
- DecodePrivatekey("C:\\rsa05\\rsa-private.key", k1);
- DecodePublickey("C:\\rsa05\\rsa-public.key", k2);
- //check
- 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");
- /*
- 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");
- }
- //successfully!
- */
- #endif
- }
- #if _GEN_RSA
- static std::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.IncorporateEntropy((byte *)seed, strlen(seed));
- std::string result;
- StringSource(message, true, new PK_EncryptorFilter(randPool, pub, new HexEncoder(new StringSink(result))));
- return result;
- }
- #endif
- #if _GEN_RSA
- static std::string RSADecryptString(const char *privFilename, const char *ciphertext)
- {
- FileSource privFile(privFilename, true, new HexDecoder);
- RSAES_OAEP_SHA_Decryptor priv(privFile);
- std::string result;
- StringSource(ciphertext, true, new HexDecoder(new PK_DecryptorFilter(GlobalRNG(), priv, new StringSink(result))));
- return result;
- }
- #endif
外加一个lib库。
/**********************************************************************************************************************/
生成cryptest工程
官方文档
在工程目录下添加CryptoPP文件夹,将编译好的lib,以及头文件放入(头文件放在include文件夹下)
流程
同时,也可以根据项目不同,生成不同的key。将项目名称作为seed替换。