RSACipher.hpp 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. #pragma once
  2. #include <openssl/err.h>
  3. #include <openssl/bio.h>
  4. #include <openssl/rsa.h>
  5. #include <openssl/pem.h>
  6. #include <string>
  7. #ifdef _DEBUG
  8. #pragma comment(lib, "libcryptoMTd.lib")
  9. #else
  10. #pragma comment(lib, "libcryptoMT.lib")
  11. #endif
  12. #pragma comment(lib, "WS2_32.lib") // some symbol are used in OpenSSL static lib
  13. #pragma comment(lib, "Crypt32.lib") // some symbol are used in OpenSSL static lib
  14. class RSACipher {
  15. private:
  16. RSA * _RsaObj;
  17. RSACipher() : _RsaObj(nullptr) {}
  18. RSACipher(RSA* lpRsa) : _RsaObj(lpRsa) {}
  19. RSACipher(const RSACipher&) = delete;
  20. RSACipher(RSACipher&&) = delete;
  21. RSACipher& operator=(const RSACipher&) = delete;
  22. RSACipher& operator=(RSACipher&&) = delete;
  23. public:
  24. enum class KeyType {
  25. PrivateKey,
  26. PublicKey
  27. };
  28. enum class KeyFormat {
  29. NotSpecified,
  30. PEM,
  31. PKCS1
  32. };
  33. ~RSACipher() {
  34. if (_RsaObj)
  35. RSA_free(_RsaObj);
  36. _RsaObj = nullptr;
  37. }
  38. static RSACipher* Create() {
  39. RSACipher* aCipher = new RSACipher(RSA_new());
  40. if (aCipher->_RsaObj == nullptr) {
  41. delete aCipher;
  42. aCipher = nullptr;
  43. }
  44. return aCipher;
  45. }
  46. bool GenerateKey(int bits, unsigned long long e = RSA_F4) {
  47. bool bSuccess = false;
  48. BIGNUM* bn_e = nullptr;
  49. bn_e = BN_new();
  50. if (bn_e == nullptr)
  51. goto ON_RSACipher_GenerateKey0_ERROR;
  52. if (!BN_set_word(bn_e, e))
  53. goto ON_RSACipher_GenerateKey0_ERROR;
  54. if (!RSA_generate_key_ex(_RsaObj, bits, bn_e, nullptr))
  55. goto ON_RSACipher_GenerateKey0_ERROR;
  56. bSuccess = true;
  57. ON_RSACipher_GenerateKey0_ERROR:
  58. if (bn_e)
  59. BN_free(bn_e);
  60. return bSuccess;
  61. }
  62. template<KeyType _Type, KeyFormat _Format = KeyFormat::NotSpecified>
  63. bool ExportKeyToFile(const std::string& filename) {
  64. static_assert(
  65. _Type == KeyType::PrivateKey || (_Format == KeyFormat::PEM || _Format == KeyFormat::PKCS1),
  66. "Not supported format."
  67. );
  68. bool bSuccess = false;
  69. BIO* bio_file = nullptr;
  70. bio_file = BIO_new_file(filename.c_str(), "w");
  71. if (bio_file == nullptr)
  72. goto ON_RSACipher_ExportKeyToFile_0_ERROR;
  73. if (_Type == KeyType::PrivateKey) {
  74. bSuccess = PEM_write_bio_RSAPrivateKey(bio_file, _RsaObj, nullptr, nullptr, 0, nullptr, nullptr) ? true : false;
  75. } else {
  76. if (_Format == KeyFormat::PEM)
  77. bSuccess = PEM_write_bio_RSA_PUBKEY(bio_file, _RsaObj) ? true : false;
  78. else if (_Format == KeyFormat::PKCS1)
  79. bSuccess = PEM_write_bio_RSAPublicKey(bio_file, _RsaObj) ? true : false;
  80. }
  81. ON_RSACipher_ExportKeyToFile_0_ERROR:
  82. return bSuccess;
  83. }
  84. template<KeyType _Type, KeyFormat _Format = KeyFormat::NotSpecified>
  85. std::string ExportKeyString() {
  86. static_assert(
  87. _Type == KeyType::PrivateKey || (_Format == KeyFormat::PEM || _Format == KeyFormat::PKCS1),
  88. "Not supported format."
  89. );
  90. std::string KeyString;
  91. BIO* bio_mem = nullptr;
  92. int len = 0;
  93. const char* lpdata = nullptr;
  94. bio_mem = BIO_new(BIO_s_mem());
  95. if (bio_mem == nullptr)
  96. goto ON_RSACipher_ExportKeyString_0_ERROR;
  97. if (_Type == KeyType::PrivateKey) {
  98. if (!PEM_write_bio_RSAPrivateKey(bio_mem, _RsaObj, nullptr, nullptr, 0, nullptr, nullptr))
  99. goto ON_RSACipher_ExportKeyString_0_ERROR;
  100. } else {
  101. if (_Format == KeyFormat::PEM) {
  102. if (!PEM_write_bio_RSA_PUBKEY(bio_mem, _RsaObj))
  103. goto ON_RSACipher_ExportKeyString_0_ERROR;
  104. } else if (_Format == KeyFormat::PKCS1) {
  105. if (!PEM_write_bio_RSAPublicKey(bio_mem, _RsaObj))
  106. goto ON_RSACipher_ExportKeyString_0_ERROR;
  107. }
  108. }
  109. len = BIO_get_mem_data(bio_mem, &lpdata);
  110. KeyString.resize(len);
  111. memcpy(KeyString.data(), lpdata, len);
  112. ON_RSACipher_ExportKeyString_0_ERROR:
  113. if (bio_mem)
  114. BIO_free_all(bio_mem);
  115. return KeyString;
  116. }
  117. template<KeyType _Type, KeyFormat _Format = KeyFormat::NotSpecified>
  118. bool ImportKeyFromFile(const std::string& filename) {
  119. static_assert(
  120. _Type == KeyType::PrivateKey || (_Format == KeyFormat::PEM || _Format == KeyFormat::PKCS1),
  121. "Not supported format."
  122. );
  123. bool bSuccess = false;
  124. BIO* bio_file = nullptr;
  125. RSA* _newRsaObj = nullptr;
  126. bio_file = BIO_new_file(filename.c_str(), "r");
  127. if (bio_file == nullptr)
  128. goto ON_RSACipher_ImportKeyFromFile_0_ERROR;
  129. if (_Type == KeyType::PrivateKey) {
  130. _newRsaObj = PEM_read_bio_RSAPrivateKey(bio_file, nullptr, nullptr, nullptr);
  131. } else {
  132. if (_Format == KeyFormat::PEM)
  133. _newRsaObj = PEM_read_bio_RSA_PUBKEY(bio_file, nullptr, nullptr, nullptr);
  134. else if (_Format == KeyFormat::PKCS1)
  135. _newRsaObj = PEM_read_bio_RSAPublicKey(bio_file, nullptr, nullptr, nullptr);
  136. }
  137. if (_newRsaObj) {
  138. RSA_free(_RsaObj);
  139. _RsaObj = _newRsaObj;
  140. bSuccess = true;
  141. }
  142. ON_RSACipher_ImportKeyFromFile_0_ERROR:
  143. if (bio_file)
  144. BIO_free_all(bio_file);
  145. return bSuccess;
  146. }
  147. template<KeyType _Type, KeyFormat _Format = KeyFormat::NotSpecified>
  148. bool ImportKeyString(const std::string& KeyString) {
  149. static_assert(
  150. _Type == KeyType::PrivateKey || (_Format == KeyFormat::PEM || _Format == KeyFormat::PKCS1),
  151. "Not supported format."
  152. );
  153. bool bSuccess = false;
  154. BIO* bio_mem = nullptr;
  155. RSA* _newRsaObj = nullptr;
  156. bio_mem = BIO_new(BIO_s_mem());
  157. if (bio_mem == nullptr)
  158. goto ON_RSACipher_ImportKeyString_0_ERROR;
  159. BIO_puts(bio_mem, KeyString.c_str());
  160. if (_Type == KeyType::PrivateKey) {
  161. _newRsaObj = PEM_read_bio_RSAPrivateKey(bio_mem, nullptr, nullptr, nullptr);
  162. } else {
  163. if (_Format == KeyFormat::PEM)
  164. _newRsaObj = PEM_read_bio_RSA_PUBKEY(bio_mem, nullptr, nullptr, nullptr);
  165. else if (_Format == KeyFormat::PKCS1)
  166. _newRsaObj = PEM_read_bio_RSAPublicKey(bio_mem, nullptr, nullptr, nullptr);
  167. }
  168. if (_newRsaObj) {
  169. RSA_free(_RsaObj);
  170. _RsaObj = _newRsaObj;
  171. bSuccess = true;
  172. }
  173. ON_RSACipher_ImportKeyString_0_ERROR:
  174. if (bio_mem)
  175. BIO_free_all(bio_mem);
  176. return bSuccess;
  177. }
  178. template<KeyType _Type = KeyType::PublicKey>
  179. int Encrypt(const void* from, int len, void* to, int padding) {
  180. int write_bytes = 0;
  181. if (_Type == KeyType::PrivateKey) {
  182. write_bytes = RSA_private_encrypt(len,
  183. reinterpret_cast<const unsigned char*>(from),
  184. reinterpret_cast<unsigned char*>(to),
  185. _RsaObj,
  186. padding);
  187. } else {
  188. write_bytes = RSA_public_encrypt(len,
  189. reinterpret_cast<const unsigned char*>(from),
  190. reinterpret_cast<unsigned char*>(to),
  191. _RsaObj,
  192. padding);
  193. }
  194. if (write_bytes == -1)
  195. write_bytes = 0;
  196. return write_bytes;
  197. }
  198. template<KeyType _Type = KeyType::PrivateKey>
  199. int Decrypt(const void* from, int len, void* to, int padding) {
  200. int write_bytes = 0;
  201. if (_Type == KeyType::PrivateKey) {
  202. write_bytes = RSA_private_decrypt(len,
  203. reinterpret_cast<const unsigned char*>(from),
  204. reinterpret_cast<unsigned char*>(to),
  205. _RsaObj,
  206. padding);
  207. } else {
  208. write_bytes = RSA_public_decrypt(len,
  209. reinterpret_cast<const unsigned char*>(from),
  210. reinterpret_cast<unsigned char*>(to),
  211. _RsaObj,
  212. padding);
  213. }
  214. if (write_bytes == -1)
  215. write_bytes = 0;
  216. return write_bytes;
  217. }
  218. };