123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267 |
- #pragma once
- #include <openssl/err.h>
- #include <openssl/bio.h>
- #include <openssl/rsa.h>
- #include <openssl/pem.h>
- #include <string>
- #ifdef _DEBUG
- #pragma comment(lib, "libcryptoMTd.lib")
- #else
- #pragma comment(lib, "libcryptoMT.lib")
- #endif
- #pragma comment(lib, "WS2_32.lib") // some symbol are used in OpenSSL static lib
- #pragma comment(lib, "Crypt32.lib") // some symbol are used in OpenSSL static lib
- class RSACipher {
- private:
- RSA * _RsaObj;
- RSACipher() : _RsaObj(nullptr) {}
- RSACipher(RSA* lpRsa) : _RsaObj(lpRsa) {}
- RSACipher(const RSACipher&) = delete;
- RSACipher(RSACipher&&) = delete;
- RSACipher& operator=(const RSACipher&) = delete;
- RSACipher& operator=(RSACipher&&) = delete;
- public:
- enum class KeyType {
- PrivateKey,
- PublicKey
- };
- enum class KeyFormat {
- NotSpecified,
- PEM,
- PKCS1
- };
- ~RSACipher() {
- if (_RsaObj)
- RSA_free(_RsaObj);
- _RsaObj = nullptr;
- }
- static RSACipher* Create() {
- RSACipher* aCipher = new RSACipher(RSA_new());
- if (aCipher->_RsaObj == nullptr) {
- delete aCipher;
- aCipher = nullptr;
- }
- return aCipher;
- }
- bool GenerateKey(int bits, unsigned long long e = RSA_F4) {
- bool bSuccess = false;
- BIGNUM* bn_e = nullptr;
- bn_e = BN_new();
- if (bn_e == nullptr)
- goto ON_RSACipher_GenerateKey0_ERROR;
- if (!BN_set_word(bn_e, e))
- goto ON_RSACipher_GenerateKey0_ERROR;
- if (!RSA_generate_key_ex(_RsaObj, bits, bn_e, nullptr))
- goto ON_RSACipher_GenerateKey0_ERROR;
- bSuccess = true;
- ON_RSACipher_GenerateKey0_ERROR:
- if (bn_e)
- BN_free(bn_e);
- return bSuccess;
- }
- template<KeyType _Type, KeyFormat _Format = KeyFormat::NotSpecified>
- bool ExportKeyToFile(const std::string& filename) {
- static_assert(
- _Type == KeyType::PrivateKey || (_Format == KeyFormat::PEM || _Format == KeyFormat::PKCS1),
- "Not supported format."
- );
- bool bSuccess = false;
- BIO* bio_file = nullptr;
- bio_file = BIO_new_file(filename.c_str(), "w");
- if (bio_file == nullptr)
- goto ON_RSACipher_ExportKeyToFile_0_ERROR;
- if (_Type == KeyType::PrivateKey) {
- bSuccess = PEM_write_bio_RSAPrivateKey(bio_file, _RsaObj, nullptr, nullptr, 0, nullptr, nullptr) ? true : false;
- } else {
- if (_Format == KeyFormat::PEM)
- bSuccess = PEM_write_bio_RSA_PUBKEY(bio_file, _RsaObj) ? true : false;
- else if (_Format == KeyFormat::PKCS1)
- bSuccess = PEM_write_bio_RSAPublicKey(bio_file, _RsaObj) ? true : false;
- }
- ON_RSACipher_ExportKeyToFile_0_ERROR:
- return bSuccess;
- }
- template<KeyType _Type, KeyFormat _Format = KeyFormat::NotSpecified>
- std::string ExportKeyString() {
- static_assert(
- _Type == KeyType::PrivateKey || (_Format == KeyFormat::PEM || _Format == KeyFormat::PKCS1),
- "Not supported format."
- );
- std::string KeyString;
- BIO* bio_mem = nullptr;
- int len = 0;
- const char* lpdata = nullptr;
- bio_mem = BIO_new(BIO_s_mem());
- if (bio_mem == nullptr)
- goto ON_RSACipher_ExportKeyString_0_ERROR;
- if (_Type == KeyType::PrivateKey) {
- if (!PEM_write_bio_RSAPrivateKey(bio_mem, _RsaObj, nullptr, nullptr, 0, nullptr, nullptr))
- goto ON_RSACipher_ExportKeyString_0_ERROR;
- } else {
- if (_Format == KeyFormat::PEM) {
- if (!PEM_write_bio_RSA_PUBKEY(bio_mem, _RsaObj))
- goto ON_RSACipher_ExportKeyString_0_ERROR;
- } else if (_Format == KeyFormat::PKCS1) {
- if (!PEM_write_bio_RSAPublicKey(bio_mem, _RsaObj))
- goto ON_RSACipher_ExportKeyString_0_ERROR;
- }
- }
- len = BIO_get_mem_data(bio_mem, &lpdata);
- KeyString.resize(len);
- memcpy(KeyString.data(), lpdata, len);
- ON_RSACipher_ExportKeyString_0_ERROR:
- if (bio_mem)
- BIO_free_all(bio_mem);
- return KeyString;
- }
- template<KeyType _Type, KeyFormat _Format = KeyFormat::NotSpecified>
- bool ImportKeyFromFile(const std::string& filename) {
- static_assert(
- _Type == KeyType::PrivateKey || (_Format == KeyFormat::PEM || _Format == KeyFormat::PKCS1),
- "Not supported format."
- );
- bool bSuccess = false;
- BIO* bio_file = nullptr;
- RSA* _newRsaObj = nullptr;
- bio_file = BIO_new_file(filename.c_str(), "r");
- if (bio_file == nullptr)
- goto ON_RSACipher_ImportKeyFromFile_0_ERROR;
- if (_Type == KeyType::PrivateKey) {
- _newRsaObj = PEM_read_bio_RSAPrivateKey(bio_file, nullptr, nullptr, nullptr);
- } else {
- if (_Format == KeyFormat::PEM)
- _newRsaObj = PEM_read_bio_RSA_PUBKEY(bio_file, nullptr, nullptr, nullptr);
- else if (_Format == KeyFormat::PKCS1)
- _newRsaObj = PEM_read_bio_RSAPublicKey(bio_file, nullptr, nullptr, nullptr);
- }
- if (_newRsaObj) {
- RSA_free(_RsaObj);
- _RsaObj = _newRsaObj;
- bSuccess = true;
- }
- ON_RSACipher_ImportKeyFromFile_0_ERROR:
- if (bio_file)
- BIO_free_all(bio_file);
- return bSuccess;
- }
- template<KeyType _Type, KeyFormat _Format = KeyFormat::NotSpecified>
- bool ImportKeyString(const std::string& KeyString) {
- static_assert(
- _Type == KeyType::PrivateKey || (_Format == KeyFormat::PEM || _Format == KeyFormat::PKCS1),
- "Not supported format."
- );
- bool bSuccess = false;
- BIO* bio_mem = nullptr;
- RSA* _newRsaObj = nullptr;
- bio_mem = BIO_new(BIO_s_mem());
- if (bio_mem == nullptr)
- goto ON_RSACipher_ImportKeyString_0_ERROR;
- BIO_puts(bio_mem, KeyString.c_str());
- if (_Type == KeyType::PrivateKey) {
- _newRsaObj = PEM_read_bio_RSAPrivateKey(bio_mem, nullptr, nullptr, nullptr);
- } else {
- if (_Format == KeyFormat::PEM)
- _newRsaObj = PEM_read_bio_RSA_PUBKEY(bio_mem, nullptr, nullptr, nullptr);
- else if (_Format == KeyFormat::PKCS1)
- _newRsaObj = PEM_read_bio_RSAPublicKey(bio_mem, nullptr, nullptr, nullptr);
- }
- if (_newRsaObj) {
- RSA_free(_RsaObj);
- _RsaObj = _newRsaObj;
- bSuccess = true;
- }
- ON_RSACipher_ImportKeyString_0_ERROR:
- if (bio_mem)
- BIO_free_all(bio_mem);
- return bSuccess;
- }
- template<KeyType _Type = KeyType::PublicKey>
- int Encrypt(const void* from, int len, void* to, int padding) {
- int write_bytes = 0;
- if (_Type == KeyType::PrivateKey) {
- write_bytes = RSA_private_encrypt(len,
- reinterpret_cast<const unsigned char*>(from),
- reinterpret_cast<unsigned char*>(to),
- _RsaObj,
- padding);
- } else {
- write_bytes = RSA_public_encrypt(len,
- reinterpret_cast<const unsigned char*>(from),
- reinterpret_cast<unsigned char*>(to),
- _RsaObj,
- padding);
- }
- if (write_bytes == -1)
- write_bytes = 0;
- return write_bytes;
- }
- template<KeyType _Type = KeyType::PrivateKey>
- int Decrypt(const void* from, int len, void* to, int padding) {
- int write_bytes = 0;
- if (_Type == KeyType::PrivateKey) {
- write_bytes = RSA_private_decrypt(len,
- reinterpret_cast<const unsigned char*>(from),
- reinterpret_cast<unsigned char*>(to),
- _RsaObj,
- padding);
- } else {
- write_bytes = RSA_public_decrypt(len,
- reinterpret_cast<const unsigned char*>(from),
- reinterpret_cast<unsigned char*>(to),
- _RsaObj,
- padding);
- }
- if (write_bytes == -1)
- write_bytes = 0;
- return write_bytes;
- }
- };
|