非对称加密算法之RSA介绍及OpenSSL中RSA常用函数使用举例
RSA算法,在1977年由Ron Rivest、Adi Shamirh和LenAdleman,在美國的麻省理工學院開發完成。這個算法的名字,來源于三位開發者的名字。RSA已經成為公鑰數據加密標準。
RSA屬于公開密鑰密碼體制。公開密鑰體制就是產生兩把密鑰,一把用于加密,一把用于解密,而且不能根據算法和其中的一把密鑰,而去推出另外的一把密鑰。在使用的時候,將公鑰公開,對方用公開的公鑰加密數據后,將密文發回,然后用另一把私鑰進行解密,從而還原出明文。
RSA算法的數學基礎是數論中的素數相關性質。RSA的算法如下:
(1)、找出兩個數p和q,其中p與q都是比較大的素數,其中p不等于q,為了保證安全性,RSA中使用的素數都比較大,且對這兩個數要進行嚴格的保密;
(2)、計算乘積n = p *q;
(3)、計算乘積f(p,q) =(p - 1) * (q - 1);
(4)、找到一個素數e,使1 < e< f(p,q),并且e與f(p,q)互素;
(5)、將(e, n)做公鑰,對明文按公式C=p^e mod n進行加密;
(6)、計算私鑰d=e^-1mod f(p,q);對密文按P = C^d mod n進行解密。
其中,e,n作為公鑰公開,任何人都可以知道。而f(p,q)作為密鑰,要進行保密。一旦f(p,q)被別人獲取,那么該RSA算法就不再安全。并且RSA算法的安全性和p,q的長度直接相關,長度越長安全性越高。因此,實際應用中p,q的長度至少為512比特。具體實現原理下圖所示。
RSA在加解密的運用中,公鑰是公開的,即有很多人都能得到,第三方也很容易竊取到e和n的數值。所以破解的關鍵就在,從e和n這兩個數值開始,想辦法求出數值d,如果能夠得到d的值,也就是能夠找到私鑰,那么就可以破解相應的信息,達到情報竊取的目的。RSA算法的安全性完全依賴于大數的分解。
優缺點:由于RSA算法的理論基礎是大數的分集,它是公認的世界難題,這就為RSA的安全性作了保障,所以它在一定程度上能抵抗外界的各種攻擊。RSA是公鑰加密系統中使用最廣的加密算法,也是第一個既可以用于數據加密,同時還可以用于數字簽名的算法。它的缺點:由于沒有直接產生大素數的技術,RSA算法密鑰產生比較麻煩;其次,為保證安全性,n一般要達到1024bit,使加密解密運算代價很高,嚴重影響了其加密速度,因此RSA算法不適合用于加密數據量大的信息;隨著保密級別的提高,密鑰的長度也在隨著增加。
RSA is vulnerable to timing attacks. In a setup where attackers can measure the timeof RSA decryption or signature operations, blinding must be used to protect theRSA operation from that attack. RSA_blinding_on(),RSA_blinding_off():protectthe RSA operation from timing attacks.
1. RSA_blinding_on():turnsblinding on for key B<rsa> and generates a random blinding factor.B<ctx> is B<NULL> or a pre-allocated and initializedB<BN_CTX>. The random number generator must be seeded prior to callingRSA_blinding_on().returns 1 on success, and 0 if an error occurred.
2. RSA_blinding_off():turnsblinding off and frees the memory used for the blinding factor.
3. RSA_check_key():validateprivate RSA keys. This function validates RSA keys. It checks that B<p>and B<q> are in fact prime, and that B<n = p*q>. It also checksthat B<d*e = 1 mod (p-1*q-1)>, and that B<dmp1>, B<dmq1> andB<iqmp> are set correctly or are B<NULL>. As such, this functioncan not be used with any arbitrary RSA key object, even if it is otherwise fitfor regular RSA operation. returns 1 if B<rsa> is a valid RSA key, and 0otherwise. -1 is returned if an error occurs while checking the key. Thisfunction does not work on RSA public keys that have only the modulus and publicexponent elements populated. It performs integrity checks on all the RSA keymaterial, so the RSA key structure must contain all the private key data too.
4. RSA_generate_key():generates akey pair and returns it in a newly allocated B<RSA> structure. Thepseudo-random number generator must be seeded prior to callingRSA_generate_key().The modulus size will be B<num> bits, and the publicexponent will be B<e>. Key sizes with B<num> E<lt> 1024should be considered insecure. The exponent is an odd number, typically 3, 17or 65537. A callback function may be used to provide feedback about the progressof the key generation. If key generation fails, RSA_generate_key() returnsB<NULL>. RSA_generate_key() goes into an infinite loop for illegal inputvalues.
5. RSA_set_ex_data():is used toset application specific data, the data is supplied in the B<arg>parameter and its precise meaning is up to the application. returns 1 onsuccess or 0 on failure.
6. RSA_get_ex_data():is used toretrieve application specific data. The data is returned to the application,this will be the same value as supplied to a previousB<RSA_set_ex_data()> call. returns the application data or 0 on failure.0 may also be valid application data but currently it can only fail if given aninvalid B<idx> parameter.
7. RSA_get_ex_new_index():returnsa new index or -1 on failure (note 0 is a valid index value).
8. RSA_new():allocate RSA objects.allocates and initializes an B<RSA> structure. It is equivalent to callingRSA_new_method(NULL).
9. RSA_free():free RSA objects. freesthe B<RSA> structure and its components. The key is erased before thememory is returned to the system.
10.?RSA_padding_xxx_xxx(): these functionsare called from the RSA encrypt, decrypt, sign and verify functions. Normallythey should not be called from application programs. However, they can also becalled directly to implement padding for other asymmetric ciphers.
11.?RSA_private_encrypt():owlevel signature operations. signs the B<flen> bytes atB<from> (usually a message digest with an algorithm identifier) using theprivate key B<rsa> and stores the signature in B<to>. B<to>must point to B<RSA_size(rsa)> bytes of memory. returns the size of thesignature (i.e.,RSA_size(rsa)).
12.?RSA_public_decrypt():ow levelsignature operations. recovers the message digest from the B<flen> byteslong signature at B<from> using the signer's public key B<rsa>.B<to> must point to a memory section large enough to hold the messagedigest (which is smaller than B<RSA_size(rsa) - 11>). B<padding> isthe padding mode that was used to sign the data. returns the size of the recoveredmessage digest.
13.?RSA_public_encrypt():encryptsthe B<flen> bytes at B<from> (usually a session key) using thepublic key B<rsa> and stores the ciphertext in B<to>. B<to>must point to RSA_size(B<rsa>) bytes of memory. returns the size of theencrypted data (i.e., RSA_size(B<rsa>)).
14.?RSA_private_decrypt():decryptsthe B<flen> bytes at B<from> using the private key B<rsa> andstores the plaintext in B<to>. B<to> must point to a memory sectionlarge enough to hold the decrypted data (which is smaller thanRSA_size(B<rsa>)). B<padding> is the padding mode that was used toencrypt the data. returns the size of the recovered plaintext.
15.?RSA_set_default_method():makesB<meth> the default method for all RSA structures created later.B<NB>: This is true only whilst no ENGINE has been set as a default forRSA, so this function is no longer recommended.
16.?RSA_get_default_method():returnsa pointer to the current default RSA_METHOD. However, the meaningfulness ofthis result is dependent on whether the ENGINE API is being used, so thisfunction is no longer recommended.
17.?RSA_set_method():selectsB<meth> to perform all operations using the key B<rsa>. This willreplace the RSA_METHOD used by the RSA key and if the previous method wassupplied by an ENGINE, the handle to that ENGINE will be released during thechange. It is possible to have RSA keys that only work with certain RSA_METHODimplementations (eg. from an ENGINE module that supports embeddedhardware-protected keys), and in such cases attempting to change the RSA_METHODfor the key can have unexpected results.
18.?RSA_get_method():returns apointer to the RSA_METHOD being used by B<rsa>. This method may or maynot be supplied by an ENGINE implementation, but if it is, the return value canonly be guaranteed to be valid as long as the RSA key itself is valid and doesnot have its implementation changed by RSA_set_method().
19.?RSA_flags():returns theB<flags> that are set for B<rsa>'s current RSA_METHOD.
20.?RSA_new_method():allocates andinitializes an RSA structure so that B<engine> will be used for the RSAoperations. If B<engine> is NULL, the default ENGINE for RSA operationsis used, and if no default ENGINE is set, the RSA_METHOD controlled byRSA_set_default_method() is used.
21.?RSA_sign():signs the messagedigest B<m> of size B<m_len> using the private key B<rsa> asspecified in PKCS #1 v2.0. It stores the signature in B<sigret> and thesignature size in B<siglen>. B<sigret> must point to RSA_size(B<rsa>)bytes of memory.
22.?RSA_verify():verifies that thesignature B<sigbuf> of size B<siglen> matches a given messagedigest B<m> of size B<m_len>. B<type> denotes the messagedigest algorithm that was used to generate the signature. B<rsa> is thesigner's public key.
23.?RSA_sign_ASN1_OCTET_STRING():signsthe octet string B<m> of size B<m_len> using the private keyB<rsa> represented in DER using PKCS #1 padding. It stores the signaturein B<sigret> and the signature size in B<siglen>. B<sigret>must point to B<RSA_size(rsa)> bytes of memory.
24.?RSA_verify_ASN1_OCTET_STRING():verifiesthat the signature B<sigbuf> of size B<siglen> is the DERrepresentation of a given octet string B<m> of size B<m_len>.B<dummy> is ignored. B<rsa> is the signer's public key.
25. RSA_size():getRSA modulus size. This function returns the RSA modulus size in bytes. It canbe used to determine how much memory must be allocated for an RSA encrypted value.
下面是測試用例代碼:
1. cryptotest.h:
#ifndef _CRYPTOTEST_H_
#define _CRYPTOTEST_H_#include <string>using namespace std;typedef enum {GENERAL = 0,ECB,CBC,CFB,OFB,TRIPLE_ECB,TRIPLE_CBC
}CRYPTO_MODE;string DES_Encrypt(const string cleartext, const string key, CRYPTO_MODE mode);
string DES_Decrypt(const string ciphertext, const string key, CRYPTO_MODE mode);string RC4_Encrypt(const string cleartext, const string key);
string RC4_Decrypt(const string ciphertext, const string key);string MD5_Digest(const string cleartext);int GenerateRSAKey(string strKey[]);
//string RSA_Encrypt(string cleartext, string key);
//string RSA_Decrypt(string ciphertext, string key);
void RSA_test1(const string cleartext);
void RSA_test2(const string cleartext);#endif //_CRYPTOTEST_H_
2. rsatest.cpp:
#include "stdafx.h"
#include "cryptotest.h"
#include "openssl/err.h"
#include <iostream>using namespace std;#define KEY_LENGTH 2048
int padding = RSA_PKCS1_PADDING;
int encrypt_len = 0;
#define PUB_EXP 3
//#define PRINT_KEYS
//#define WRITE_TO_FILEint GenerateRSAKey(string strKey[])
{size_t pri_len; // Length of private keysize_t pub_len; // Length of public keychar *pri_key = NULL; // Private keychar *pub_key = NULL; // Public keyRSA* keypair = RSA_generate_key(KEY_LENGTH, RSA_3, NULL, NULL);BIO *pri = BIO_new(BIO_s_mem());BIO *pub = BIO_new(BIO_s_mem());PEM_write_bio_RSAPrivateKey(pri, keypair, NULL, NULL, 0, NULL, NULL);PEM_write_bio_RSAPublicKey(pub, keypair);pri_len = BIO_pending(pri);pub_len = BIO_pending(pub);pri_key = new char[pri_len + 1];pub_key = new char[pub_len + 1];BIO_read(pri, pri_key, pri_len);BIO_read(pub, pub_key, pub_len);pri_key[pri_len] = '\0';pub_key[pub_len] = '\0';strKey[0] = pub_key;strKey[1] = pri_key;//printf("\n%s\n%s\n", pri_key, pub_key);RSA_free(keypair);BIO_free_all(pub);BIO_free_all(pri);delete [] pri_key;delete [] pub_key;return 0;
}RSA* createRSA(unsigned char* key, int flag)
{RSA *rsa= NULL;BIO *keybio ;keybio = BIO_new_mem_buf(key, -1);if (keybio==NULL) {printf( "Failed to create key BIO");return 0;}if(flag)rsa = PEM_read_bio_RSA_PUBKEY(keybio, &rsa, NULL, NULL);elsersa = PEM_read_bio_RSAPrivateKey(keybio, &rsa, NULL, NULL);if(rsa == NULL)printf( "Failed to create RSA");return rsa;
}int public_encrypt(unsigned char* data, int data_len, unsigned char* key, unsigned char* encrypted)
{RSA * rsa = createRSA(key, 1);int result = RSA_public_encrypt(data_len, data, encrypted, rsa, padding);return result;
}int private_decrypt(unsigned char* enc_data, int data_len, unsigned char* key, unsigned char* decrypted)
{RSA * rsa = createRSA(key, 0);int result = RSA_private_decrypt(data_len,enc_data,decrypted,rsa,padding);return result;
}int private_encrypt(unsigned char* data, int data_len, unsigned char* key, unsigned char* encrypted)
{RSA * rsa = createRSA(key, 0);int result = RSA_private_encrypt(data_len, data, encrypted, rsa, padding);return result;
}int public_decrypt(unsigned char* enc_data, int data_len, unsigned char* key, unsigned char* decrypted)
{RSA * rsa = createRSA(key, 1);int result = RSA_public_decrypt(data_len, enc_data, decrypted, rsa, padding);return result;
}void printLastError(char *msg)
{char * err = (char*)malloc(130);;ERR_load_crypto_strings();ERR_error_string(ERR_get_error(), err);printf("%s ERROR: %s\n", msg, err);free(err);
}void RSA_test1(const string cleartext)
{//char plainText[2048/8] = "Hello this is Ravi"; //key length : 2048string plainText = cleartext;//下面的公鑰和私鑰是通過命令行方式獲取的//char publicKey[]="-----BEGIN PUBLIC KEY-----\n"string publicKey = "-----BEGIN PUBLIC KEY-----\n" \"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy8Dbv8prpJ/0kKhlGeJY\n" \"ozo2t60EG8L0561g13R29LvMR5hyvGZlGJpmn65+A4xHXInJYiPuKzrKUnApeLZ+\n" \"vw1HocOAZtWK0z3r26uA8kQYOKX9Qt/DbCdvsF9wF8gRK0ptx9M6R13NvBxvVQAp\n" \"fc9jB9nTzphOgM4JiEYvlV8FLhg9yZovMYd6Wwf3aoXK891VQxTr/kQYoq1Yp+68\n" \"i6T4nNq7NWC+UNVjQHxNQMQMzU6lWCX8zyg3yH88OAQkUXIXKfQ+NkvYQ1cxaMoV\n" \"PpY72+eVthKzpMeyHkBn7ciumk5qgLTEJAfWZpe4f4eFZj/Rc8Y8Jj2IS5kVPjUy\n" \"wQIDAQAB\n" \"-----END PUBLIC KEY-----\n";//char privateKey[]="-----BEGIN RSA PRIVATE KEY-----\n"string privateKey = "-----BEGIN RSA PRIVATE KEY-----\n"\"MIIEowIBAAKCAQEAy8Dbv8prpJ/0kKhlGeJYozo2t60EG8L0561g13R29LvMR5hy\n"\"vGZlGJpmn65+A4xHXInJYiPuKzrKUnApeLZ+vw1HocOAZtWK0z3r26uA8kQYOKX9\n"\"Qt/DbCdvsF9wF8gRK0ptx9M6R13NvBxvVQApfc9jB9nTzphOgM4JiEYvlV8FLhg9\n"\"yZovMYd6Wwf3aoXK891VQxTr/kQYoq1Yp+68i6T4nNq7NWC+UNVjQHxNQMQMzU6l\n"\"WCX8zyg3yH88OAQkUXIXKfQ+NkvYQ1cxaMoVPpY72+eVthKzpMeyHkBn7ciumk5q\n"\"gLTEJAfWZpe4f4eFZj/Rc8Y8Jj2IS5kVPjUywQIDAQABAoIBADhg1u1Mv1hAAlX8\n"\"omz1Gn2f4AAW2aos2cM5UDCNw1SYmj+9SRIkaxjRsE/C4o9sw1oxrg1/z6kajV0e\n"\"N/t008FdlVKHXAIYWF93JMoVvIpMmT8jft6AN/y3NMpivgt2inmmEJZYNioFJKZG\n"\"X+/vKYvsVISZm2fw8NfnKvAQK55yu+GRWBZGOeS9K+LbYvOwcrjKhHz66m4bedKd\n"\"gVAix6NE5iwmjNXktSQlJMCjbtdNXg/xo1/G4kG2p/MO1HLcKfe1N5FgBiXj3Qjl\n"\"vgvjJZkh1as2KTgaPOBqZaP03738VnYg23ISyvfT/teArVGtxrmFP7939EvJFKpF\n"\"1wTxuDkCgYEA7t0DR37zt+dEJy+5vm7zSmN97VenwQJFWMiulkHGa0yU3lLasxxu\n"\"m0oUtndIjenIvSx6t3Y+agK2F3EPbb0AZ5wZ1p1IXs4vktgeQwSSBdqcM8LZFDvZ\n"\"uPboQnJoRdIkd62XnP5ekIEIBAfOp8v2wFpSfE7nNH2u4CpAXNSF9HsCgYEA2l8D\n"\"JrDE5m9Kkn+J4l+AdGfeBL1igPF3DnuPoV67BpgiaAgI4h25UJzXiDKKoa706S0D\n"\"4XB74zOLX11MaGPMIdhlG+SgeQfNoC5lE4ZWXNyESJH1SVgRGT9nBC2vtL6bxCVV\n"\"WBkTeC5D6c/QXcai6yw6OYyNNdp0uznKURe1xvMCgYBVYYcEjWqMuAvyferFGV+5\n"\"nWqr5gM+yJMFM2bEqupD/HHSLoeiMm2O8KIKvwSeRYzNohKTdZ7FwgZYxr8fGMoG\n"\"PxQ1VK9DxCvZL4tRpVaU5Rmknud9hg9DQG6xIbgIDR+f79sb8QjYWmcFGc1SyWOA\n"\"SkjlykZ2yt4xnqi3BfiD9QKBgGqLgRYXmXp1QoVIBRaWUi55nzHg1XbkWZqPXvz1\n"\"I3uMLv1jLjJlHk3euKqTPmC05HoApKwSHeA0/gOBmg404xyAYJTDcCidTg6hlF96\n"\"ZBja3xApZuxqM62F6dV4FQqzFX0WWhWp5n301N33r0qR6FumMKJzmVJ1TA8tmzEF\n"\"yINRAoGBAJqioYs8rK6eXzA8ywYLjqTLu/yQSLBn/4ta36K8DyCoLNlNxSuox+A5\n"\"w6z2vEfRVQDq4Hm4vBzjdi3QfYLNkTiTqLcvgWZ+eX44ogXtdTDO7c+GeMKWz4XX\n"\"uJSUVL5+CVjKLjZEJ6Qc2WZLl94xSwL71E41H4YciVnSCQxVc4Jw\n"\"-----END RSA PRIVATE KEY-----\n";unsigned char encrypted[4098] = {};unsigned char decrypted[4098] = {};//int encrypted_length= public_encrypt((unsigned char*)plainText,strlen(plainText),(unsigned char*)publicKey,encrypted);int encrypted_length= public_encrypt((unsigned char*)plainText.c_str(), plainText.length(), (unsigned char*)publicKey.c_str(), encrypted);if (encrypted_length == -1) {printLastError("Public Encrypt failed ");exit(0);}printf("Encrypted length =%d\n", encrypted_length);int decrypted_length = private_decrypt(encrypted, encrypted_length, (unsigned char*)privateKey.c_str(), decrypted);if (decrypted_length == -1) {printLastError("Private Decrypt failed ");exit(0);}printf("Decrypted Text =%s\n", decrypted);printf("Decrypted Length =%d\n", decrypted_length);encrypted_length= private_encrypt((unsigned char*)plainText.c_str(), plainText.length(),(unsigned char*)privateKey.c_str(), encrypted);if(encrypted_length == -1) {printLastError("Private Encrypt failed");exit(0);}printf("Encrypted length =%d\n", encrypted_length);decrypted_length = public_decrypt(encrypted, encrypted_length, (unsigned char*)publicKey.c_str(), decrypted);if(decrypted_length == -1) {printLastError("Public Decrypt failed");exit(0);}printf("Decrypted Text =%s\n", decrypted);printf("Decrypted Length =%d\n", decrypted_length);
}void RSA_test2(const string cleartext)
{size_t pri_len; // Length of private keysize_t pub_len; // Length of public keychar *pri_key; // Private keychar *pub_key; // Public keychar msg[KEY_LENGTH/8]; // Message to encryptchar *encrypt = NULL; // Encrypted messagechar *decrypt = NULL; // Decrypted messagechar *err; // Buffer for any error messagesstring str;// Generate key pair//printf("Generating RSA (%d bits) keypair...", KEY_LENGTH);fflush(stdout);RSA *keypair = RSA_generate_key(KEY_LENGTH, PUB_EXP, NULL, NULL);// To get the C-string PEM form:BIO *pri = BIO_new(BIO_s_mem());BIO *pub = BIO_new(BIO_s_mem());PEM_write_bio_RSAPrivateKey(pri, keypair, NULL, NULL, 0, NULL, NULL);PEM_write_bio_RSAPublicKey(pub, keypair);pri_len = BIO_pending(pri);pub_len = BIO_pending(pub);pri_key = (char*)malloc(pri_len + 1);pub_key = (char*)malloc(pub_len + 1);BIO_read(pri, pri_key, pri_len);BIO_read(pub, pub_key, pub_len);pri_key[pri_len] = '\0';pub_key[pub_len] = '\0';#ifdef PRINT_KEYSprintf("\n%s\n%s\n", pri_key, pub_key);
#endif//printf("done.\n");// Get the message to encryptprintf("Message to encrypt: ");fgets(msg, KEY_LENGTH-1, stdin);msg[strlen(msg)-1] = '\0';//string msg = cleartext;//cout<<"length:"<<strlen(msg)<<endl;// Encrypt the messageencrypt = (char*)malloc(RSA_size(keypair));int encrypt_len;err = (char*)malloc(130);if((encrypt_len = RSA_public_encrypt(strlen(msg)+1, (unsigned char*)msg, (unsigned char*)encrypt, keypair, RSA_PKCS1_OAEP_PADDING)) == -1) {//if((encrypt_len = RSA_public_encrypt(msg.length(), (unsigned char*)msg.c_str(), (unsigned char*)encrypt, keypair, RSA_PKCS1_OAEP_PADDING)) == -1) {ERR_load_crypto_strings();ERR_error_string(ERR_get_error(), err);fprintf(stderr, "Error encrypting message: %s\n", err);goto free_stuff;}#ifdef WRITE_TO_FILE// Write the encrypted message to a fileFILE *out = fopen("out.bin", "w");fwrite(encrypt, sizeof(*encrypt), RSA_size(keypair), out);fclose(out);printf("Encrypted message written to file.\n");free(encrypt);encrypt = NULL;// Read it backprintf("Reading back encrypted message and attempting decryption...\n");encrypt = (char*)malloc(RSA_size(keypair));out = fopen("out.bin", "r");fread(encrypt, sizeof(*encrypt), RSA_size(keypair), out);fclose(out);
#endif// Decrypt itdecrypt = (char*)malloc(encrypt_len);//decrypt = new char[encrypt_len + 1];//memset(decrypt, encrypt_len+1, 0);if(RSA_private_decrypt(encrypt_len, (unsigned char*)encrypt, (unsigned char*)decrypt, keypair, RSA_PKCS1_OAEP_PADDING) == -1) {ERR_load_crypto_strings();ERR_error_string(ERR_get_error(), err);fprintf(stderr, "Error decrypting message: %s\n", err);goto free_stuff;}printf("Decrypted message: %s\n", decrypt);free_stuff:RSA_free(keypair);BIO_free_all(pub);BIO_free_all(pri);free(pri_key);free(pub_key);free(encrypt);free(decrypt);free(err);
}
3. main.cpp:
#include "stdafx.h"
#include "cryptotest.h"
#include <iostream>
#include <string>using namespace std;int main(int argc, char* argv[])
{//string strKey[2] = {};//[0]:public key; [1]:private key //GenerateRSAKey(strKey);//cout<<"public key:"<<endl<<strKey[0]<<endl;//cout<<"private key:"<<endl<<strKey[1]<<endl;string cleartext = "中國北京12345$abcde%ABCDE@!!!!";if (cleartext.length() > 256) {cout<<"cleartext too length!!!"<<endl;return -1;}RSA_test1(cleartext);//RSA_test2(cleartext);cout<<"ok!!!"<<endl;return 0;
}
RSA算法理論摘自:
?
1. 《基于DES_RSA加密算法的改進與實現》
2. 《DES和RSA混合加密算法的研究》
測試代碼中:
1. RSA_test1中的代碼主要來自于: http://hayageek.com/rsa-encryption-decryption-openssl-c/
2. RSA_test2中的代碼主要來自于: https://shanetully.com/2012/04/simple-public-key-encryption-with-rsa-and-openssl/
GitHub:https://github.com/fengbingchun/OpenSSL_Test
總結
以上是生活随笔為你收集整理的非对称加密算法之RSA介绍及OpenSSL中RSA常用函数使用举例的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 利用CxImage实现编解码Gif图像代
- 下一篇: 接口冲突的一种解决方法