RSA算法的原理就不提了,網上有不少介紹的文章,由於項目中使用RSA加密,因此須要找一個RSA加密的算法,以前嘗試過使用Crypto++庫,無奈Crypto++其中使用了大量的模版,各類繼承,看着頭大,github上一些我的代碼又不敢使用,最後選用了polarssl內的RSA算法,本文主要講解VS2010如何使用polarssl內的RSA模塊來進行RSA加密解密,方便本身和你們之後使用。git
polarssl被ARM 公司收購,並更名爲 mbed TLS,能夠從其官網下載,或者從這裏下載以前版本。博主下載的是polarssl-1.2.17版本,下載完成後解壓,目錄結構以下:github
默認彷佛是沒有導出函數的,因此直接把源碼放入本身工程內使用,新建win32控制檯項目,將Library下的全部文件以及include目錄下的polarssl目錄複製到項目目錄,增長一個文件,寫入以下內容:算法
#include <stdio.h> #include <stdlib.h> #include <assert.h> #include <string> #include "polarssl/entropy.h" #include "polarssl/ctr_drbg.h" #include "polarssl/rsa.h" #include "polarssl/aes.h" #include "polarssl/base64.h" const unsigned int RSA_KEY_SIZE = 1024; // RSA 公鑰的位數 const unsigned int AES_KEY_SIZE = 256; const unsigned int EXPONENT = 65537; const unsigned int BUFFER_SIZE = 1024; class rsa { public: rsa() { memset(rsa_n, 0, BUFFER_SIZE); memset(rsa_e, 0, BUFFER_SIZE); memset(rsa_d, 0, BUFFER_SIZE); memset(rsa_p, 0, BUFFER_SIZE); memset(rsa_q, 0, BUFFER_SIZE); memset(rsa_dp, 0, BUFFER_SIZE); memset(rsa_dq, 0, BUFFER_SIZE); memset(rsa_qp, 0, BUFFER_SIZE); n_len = BUFFER_SIZE; e_len = BUFFER_SIZE; d_len = BUFFER_SIZE; p_len = BUFFER_SIZE; q_len = BUFFER_SIZE; dp_len = BUFFER_SIZE; dq_len = BUFFER_SIZE; qp_len = BUFFER_SIZE; } unsigned char rsa_n[BUFFER_SIZE]; unsigned char rsa_e[BUFFER_SIZE]; unsigned char rsa_d[BUFFER_SIZE]; unsigned char rsa_p[BUFFER_SIZE]; unsigned char rsa_q[BUFFER_SIZE]; unsigned char rsa_dp[BUFFER_SIZE]; unsigned char rsa_dq[BUFFER_SIZE]; unsigned char rsa_qp[BUFFER_SIZE]; unsigned int n_len; unsigned int e_len; unsigned int d_len; unsigned int p_len; unsigned int q_len; unsigned int dp_len; unsigned int dq_len; unsigned int qp_len; }; void generate_rsa(rsa& r) { // 生成RSA密鑰對 rsa_context rsa; entropy_context entropy; ctr_drbg_context ctr_drbg; entropy_init(&entropy); assert(ctr_drbg_init(&ctr_drbg, entropy_func, &entropy, nullptr, 0) == 0); rsa_init(&rsa, RSA_PKCS_V15, 0); assert(rsa_gen_key(&rsa, ctr_drbg_random, &ctr_drbg, RSA_KEY_SIZE, EXPONENT) == 0); assert(mpi_write_binary(&rsa.N, r.rsa_n, BUFFER_SIZE) == 0); assert(mpi_write_binary(&rsa.E, r.rsa_e, BUFFER_SIZE) == 0); assert(mpi_write_binary(&rsa.D, r.rsa_d, BUFFER_SIZE) == 0); assert(mpi_write_binary(&rsa.P, r.rsa_p, BUFFER_SIZE) == 0); assert(mpi_write_binary(&rsa.Q, r.rsa_q, BUFFER_SIZE) == 0); assert(mpi_write_binary(&rsa.DP, r.rsa_dp, BUFFER_SIZE) == 0); assert(mpi_write_binary(&rsa.DQ, r.rsa_dq, BUFFER_SIZE) == 0); assert(mpi_write_binary(&rsa.QP, r.rsa_qp, BUFFER_SIZE) == 0); //寫入文件保存,每一個間隔1024字節 FILE * fp = fopen("rsa","wb"); fwrite(r.rsa_n,BUFFER_SIZE,1,fp); fwrite(r.rsa_e,BUFFER_SIZE,1,fp); fwrite(r.rsa_d,BUFFER_SIZE,1,fp); fwrite(r.rsa_p,BUFFER_SIZE,1,fp); fwrite(r.rsa_q,BUFFER_SIZE,1,fp); fwrite(r.rsa_dp,BUFFER_SIZE,1,fp); fwrite(r.rsa_dq,BUFFER_SIZE,1,fp); fwrite(r.rsa_qp,BUFFER_SIZE,1,fp); fclose(fp); } void read_rsa(rsa& r) { //讀取保存的RSA相關信息 FILE * fp = fopen("rsa","rb"); fread(r.rsa_n,BUFFER_SIZE,1,fp); fread(r.rsa_e,BUFFER_SIZE,1,fp); fread(r.rsa_d,BUFFER_SIZE,1,fp); fread(r.rsa_p,BUFFER_SIZE,1,fp); fread(r.rsa_q,BUFFER_SIZE,1,fp); fread(r.rsa_dp,BUFFER_SIZE,1,fp); fread(r.rsa_dq,BUFFER_SIZE,1,fp); fread(r.rsa_qp,BUFFER_SIZE,1,fp); fclose(fp); } // 加密 void encrypt( const rsa &r, const unsigned char* plaintext, unsigned int plaintext_size, unsigned char *ciphertext, unsigned int *ciphertext_size) { rsa_context rsa; entropy_context entropy; ctr_drbg_context ctr_drbg; entropy_init(&entropy); assert(ctr_drbg_init(&ctr_drbg, entropy_func, &entropy, nullptr, 0) == 0); rsa_init(&rsa, RSA_PKCS_V15, 0); assert(mpi_read_binary(&rsa.N, r.rsa_n, BUFFER_SIZE) == 0); assert(mpi_read_binary(&rsa.E, r.rsa_e, BUFFER_SIZE) == 0); *ciphertext_size = rsa.len = (mpi_msb(&rsa.N) + 7) >> 3; assert(rsa_pkcs1_encrypt(&rsa, ctr_drbg_random, &ctr_drbg, RSA_PUBLIC, plaintext_size, plaintext, ciphertext) == 0); } // 解密 void decrypt( const rsa &r, const unsigned char* ciphertext, unsigned int ciphertext_size, unsigned char *plaintext, unsigned int &plaintext_size) { rsa_context rsa; entropy_context entropy; ctr_drbg_context ctr_drbg; entropy_init(&entropy); assert(ctr_drbg_init(&ctr_drbg, entropy_func, &entropy, nullptr, 0) == 0); rsa_init(&rsa, RSA_PKCS_V15, 0); assert(mpi_read_binary(&rsa.N, r.rsa_n, BUFFER_SIZE) == 0); assert(mpi_read_binary(&rsa.E, r.rsa_e, BUFFER_SIZE) == 0); assert(mpi_read_binary(&rsa.D, r.rsa_d, BUFFER_SIZE) == 0); assert(mpi_read_binary(&rsa.P, r.rsa_p, BUFFER_SIZE) == 0); assert(mpi_read_binary(&rsa.Q, r.rsa_q, BUFFER_SIZE) == 0); assert(mpi_read_binary(&rsa.DP, r.rsa_dp, BUFFER_SIZE) == 0); assert(mpi_read_binary(&rsa.DQ, r.rsa_dq, BUFFER_SIZE) == 0); assert(mpi_read_binary(&rsa.QP, r.rsa_qp, BUFFER_SIZE) == 0); rsa.len = (mpi_msb(&rsa.N) + 7) >> 3; assert(rsa_pkcs1_decrypt(&rsa, ctr_drbg_random, &ctr_drbg, RSA_PRIVATE, &plaintext_size, ciphertext, plaintext, plaintext_size) == 0); } int main() { rsa r; generate_rsa(r); //read_rsa(r);從generate_rsa保存的RSA文件中讀取RSA參數信息 unsigned char plaintext[] = "testrsa"; unsigned char ciphertext[BUFFER_SIZE] = { 0 }; unsigned int ciphertext_len = BUFFER_SIZE; encrypt(r, plaintext, sizeof(plaintext), ciphertext, &ciphertext_len); size_t dstlen = 0; base64_encode(NULL,&dstlen,ciphertext,ciphertext_len);//第一次獲取目標長度 unsigned char* dstbuf = new unsigned char[dstlen+1]; memset(dstbuf,0,dstlen+1); base64_encode(dstbuf,&dstlen,ciphertext,ciphertext_len);//轉換爲BASE64編碼 printf("%s\n",dstbuf); unsigned char output[BUFFER_SIZE] = { 0 }; unsigned int output_len = BUFFER_SIZE; dstlen = 0; base64_decode(NULL,&dstlen,dstbuf,strlen((const char*)dstbuf)); unsigned char* srcbuf = new unsigned char[dstlen]; base64_decode(srcbuf,&dstlen,dstbuf,strlen((const char*)dstbuf)); decrypt(r, srcbuf, dstlen, output, output_len); printf("%s\n",output); system("pause"); return 0; }
運行結果:dom
假設已經得到RSA相關參數信息,則只須要將參數設置便可,不須要從新生成RSA密鑰信息,上述代碼中將main函數改成以下便可測試:函數
int main() { rsa r; //generate_rsa(r); read_rsa(r);//從generate_rsa保存的RSA文件中讀取RSA參數信息 unsigned char plaintext[] = "testrsa"; unsigned char ciphertext[BUFFER_SIZE] = { 0 }; unsigned int ciphertext_len = BUFFER_SIZE; encrypt(r, plaintext, sizeof(plaintext), ciphertext, &ciphertext_len); size_t dstlen = 0; base64_encode(NULL,&dstlen,ciphertext,ciphertext_len);//第一次獲取目標長度 unsigned char* dstbuf = new unsigned char[dstlen+1]; memset(dstbuf,0,dstlen+1); base64_encode(dstbuf,&dstlen,ciphertext,ciphertext_len);//轉換爲BASE64編碼 printf("%s\n",dstbuf); unsigned char output[BUFFER_SIZE] = { 0 }; unsigned int output_len = BUFFER_SIZE; dstlen = 0; base64_decode(NULL,&dstlen,dstbuf,strlen((const char*)dstbuf)); unsigned char* srcbuf = new unsigned char[dstlen]; base64_decode(srcbuf,&dstlen,dstbuf,strlen((const char*)dstbuf)); decrypt(r, srcbuf, dstlen, output, output_len); printf("%s\n",output); system("pause"); return 0; }