Using the OpenSSL library for RSA, AES data encryption OpenSSL is a library that can be easily encrypted and decrypted, and can be used to encrypt data that needs to be transmitted over the network. Asymmetric encryption can be used: Public key encryption, private key decryption. OpenSSL provides support for RSA, but RSA has low computational efficiency, so it is common practice to encrypt the data using a symmetric key and then pass it on to the target party only after the current valid temporarily generated symmetric key is encrypted with the public key of the asymmetric key. The target party uses the agreed-on asymmetric key to solve the secret key, get the data encryption key, and then decrypt the data, get the data, this use is very common, it can be considered as the clipping of HTTPS. Symmetric key encryption can choose AES, which is better than DES. The OpenSSL library is from http://www.openssl.org/, and after downloading to the OpenSSL source, start compiling:
the practice of generating a dynamic library: 1, install ACTIVEPERL2, enter the folder of OpenSSL, run: Perl Configure vc-win32--prefix=c:\openssl-dll3, enter Vc/bin directory, run VCVARS32. BAT Set environment variable 4, return to the OpenSSL directory, run MS\DO_MS5, execute compile nmake-f ms\ntdll.mak6 in the OpenSSL directory, copy the necessary build to the prefix defined directory nmake-f ms\ Ntdll.mak Install Note: You can determine the compilation of MT, MD libraries by modifying the Cflag in the Ntdll.mak file
the practice of generating a static library: 1, install ACTIVEPERL2, perl configure Vc-win32--prefix=c:\openssl-lib3, MS\DO_MS.BAT4, Nmake-f ms\nt.mak5, Nmake-f ms\ Nt.mak Install Note: You can determine the compilation of MT, MD libraries by modifying the Cflag in the Nt.mak file. When re-compiling, delete the generated object.
RSA Plus decryption requires first generating RSA public and RSA private keys with the OpenSSL tool。 Method: 1, generate the private key: OpenSSL genrsa-out Privkey.pem 1024, 2, the public key is generated according to the private key: OpenSSL rsa-in privkey.pem-pubout. 1024 is only used for testing, 2048-bit is more safe.
RSA Encryption Part code demo:
std::string encodersakeyfile (const std::string& strpemfilename, const std::string& strdata) {if (StrP Emfilename.empty () | | Strdata.empty ()) {assert (false); Return ""; } file* hpubkeyfile = NULL; if (fopen_s (&hpubkeyfile, Strpemfilename.c_str (), "RB") | | hpubkeyfile = = NULL) {assert (false); Return ""; } std::string strret; rsa* Prsapublickey = Rsa_new (); if (Pem_read_rsa_pubkey (hpubkeyfile, &prsapublickey, 0, 0) = = NULL) {assert (false); Return ""; } int nlen = Rsa_size (Prsapublickey); char* Pencode = new Char[nlen + 1]; int ret = Rsa_public_encrypt (Strdata.length (), (const unsigned char*) strdata.c_str (), (unsigned char*) Pencode, Prsapublickey, rsa_pkcs1_padding); if (ret >= 0) {strret = std::string (Pencode, ret); }
Delete[] Pencode; Rsa_free (Prsapublickey); Fclose (Hpubkeyfile); Crypto_cleanup_all_ex_data (); return strret; }
RSA decryption Part code demo:
std::string decodersakeyfile (const std::string& strpemfilename, const std::string& strdata) {if (StrP Emfilename.empty () | | Strdata.empty ()) {assert (false); Return ""; } file* hprikeyfile = NULL; if (fopen_s (&hprikeyfile, Strpemfilename.c_str (), "RB") | | hprikeyfile = = NULL) {assert (false); Return ""; } std::string strret; rsa* Prsaprikey = Rsa_new (); if (Pem_read_rsaprivatekey (hprikeyfile, &prsaprikey, 0, 0) = = NULL) {assert (false); Return ""; } int nlen = Rsa_size (Prsaprikey); char* Pdecode = new Char[nlen+1]; int ret = Rsa_private_decrypt (Strdata.length (), (const unsigned char*) strdata.c_str (), (unsigned char*) Pdecode, Prsaprikey, rsa_pkcs1_padding); if (ret >= 0) {strret = std::string ((char*) Pdecode, ret); }
delete [] pdecode; Rsa_free (Prsaprikey); Fclose (Hprikeyfile); Crypto_cleanup_all_ex_data (); return strret; }
In the RSA API, when using the parameter rsa_pkcs1_padding, the plaintext length cannot be greater than the cipher length-11; When the parameter rsa_no_padding is used, the clear text length needs to be exactly 128.
AES Encryption Part code:
std::string encodeaes (const std::string& Password, const std::string& data) {Aes_key aes_key; if (Aes_set_encrypt_key (const unsigned char*) password.c_str (), Password.length () * 8, &aes_key) < 0) { ASSERT (FALSE); Return ""; } std::string strret; std::string data_bak = data; unsigned int data_length = Data_bak.length (); int padding = 0; if (data_bak.length ()% Aes_block_size > 0) {padding = aes_block_size-data_bak.length ()% Aes_blo Ck_size; } data_length + = padding; while (padding > 0) {data_bak + = '; padding--; } for (unsigned int i = 0; i < data_length/aes_block_size; i++) {std::string str16 = Data_bak. substr (I*aes_block_size, aes_block_size); unsigned char out[aes_block_size]; :: memset (out, 0, aes_block_size); Aes_encrypt ((constunsigned char*) str16.c_str (), out, &aes_key); Strret + = std::string ((const char*) out, aes_block_size); } return strret; }
AES Decryption Part code:
std::string Decodeaes (const std::string& strpassword, const std::string& strdata) { Aes_key aes_key;< C6/>if (Aes_set_decrypt_key (const unsigned char*) strpassword.c_str (), Strpassword.length () * 8, &aes_key) < 0) C7/>{ assert (false); Return ""; } std::string strret; for (unsigned int i = 0; i < strdata.length ()/aes_block_size; i++) { std::string str16 = Strdata.substr (i*aes _block_size, aes_block_size); unsigned char out[aes_block_size]; :: memset (out, 0, aes_block_size); Aes_decrypt (const unsigned char*) str16.c_str (), out, &aes_key); Strret + = std::string ((const char*) out, aes_block_size); } return strret; }
AES encryption, the block size must be 128 bits (16 bytes), if not, then to complement, the key length can choose 128-bit, 192-bit, 256-bit.
different language decryption supplement: When decrypting with Python, public key may require a pkcs#1 format, and OpenSSL is not supported, and OpenSSL defaults to public key in the X509 format, so if you want to create public on top The key is provided to Python and needs to be converted from the X509 format to the pkcs#1 format first. The data on the network shows that PHP has an API to support this conversion, but I haven't tried it. Since my private key is 2048 bits, so it can be very convenient to implement X509 to pkcs#1, conversion is reversible, said pkcs#1 to X509 method: first delete the head and foot "RSA", and then the second line at the beginning of adding text " MIIBIJANBGKQHKIG9W0BAQEFAAOCAQ8A ", finally, aligns the text. What if the private key is not 2048? You can use the PHP API to turn around, or go to the web to find the conversion data to solve. RSA key Formats. 2013.11.27. Some information: Http://www.ibm.com/developerworks/cn/linux/l-openssl.htmlhttp://www.cnblogs.com/aLittleBitCool /archive/2011/09/22/2185418.html Clear Text length limit: http://bbs.chinaunix.net/thread-1860492-1-1.html AES Encryption Example:/HTTP blog.csdn.net/wklnewlife/article/details/8244893http://www.lovelucy.info/openssl-aes-encryption.htmlhttp:// WWW.THINKEMB.COM/WORDPRESS/?P=18 compilation Data supplement: http://developer.covenanteyes.com/building-openssl-for-visual-studio/
Using the OpenSSL library for RSA, AES data encryption