上周折腾加密与解密,用了openssl, crypto++, polarssl, cyassl, 说起真的让人很沮丧,只有openssl & polarssl两个库的RSA & AES 加密和解密,我用起来了,crypto++各种模板,各种多继承,看的头大,而且对各种常用的加密算法也不了解,所以这个库我在折腾了一天之后就放弃了;cyassl这个库现在没什么印象了;openssl没什么好说的,用起来很方便,尤其是使用win32openssl,都不用自己编译,下载下来安装好了就能用,着实方便;但是我是要在移动终端使用RSA & AES,研究了半天怎么只使用openssl的源代码,发现还真是麻烦;总之呢,现在我决定使用polarssl,接口简单易用,而且使用源代码进行编译,都是C文件,肯定是跨平台的了,很小,很精悍,下面帖出使用polarssl实现的RSA & AES加密和解密的过程,便于日后直接使用
#include#include #include #include #include "polarssl/entropy.h"#include "polarssl/ctr_drbg.h"#include "polarssl/rsa.h"#include "polarssl/aes.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); } 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 = BUFFER_SIZE; unsigned int e_len = BUFFER_SIZE; unsigned int d_len = BUFFER_SIZE; unsigned int p_len = BUFFER_SIZE; unsigned int q_len = BUFFER_SIZE; unsigned int dp_len = BUFFER_SIZE; unsigned int dq_len = BUFFER_SIZE; unsigned int qp_len = BUFFER_SIZE;};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); //puts(r.rsa_n); //puts(r.rsa_e);}// 加密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); 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);}void test_aes(){ // 产生随机的AES key buffer ctr_drbg_context ctr_drbg; entropy_context entropy; unsigned char aes_key_buf[AES_KEY_SIZE] = { 0 }; entropy_init(&entropy); assert(ctr_drbg_init(&ctr_drbg, entropy_func, &entropy, nullptr, 0) == 0); ctr_drbg_set_prediction_resistance(&ctr_drbg, CTR_DRBG_PR_OFF); ctr_drbg_random(&ctr_drbg, aes_key_buf, AES_KEY_SIZE); // 生成AES aes_context aes_enc, aes_dec; aes_init(&aes_enc); aes_init(&aes_dec); assert(aes_setkey_enc(&aes_enc, aes_key_buf, AES_KEY_SIZE) == 0); assert(aes_setkey_dec(&aes_dec, aes_key_buf, AES_KEY_SIZE) == 0); // 加密 & 解密. 明文与密文的长度是固定的, 都是16bytes /* const unsigned int DATA_SIZE = 16; unsigned char plaintext[DATA_SIZE] = { 0 }; unsigned char ciphertext[DATA_SIZE] = { 0 }; sprintf((char*)plaintext, "%s", "moyakukudi"); assert(aes_crypt_ecb(&aes_enc, AES_ENCRYPT, plaintext, ciphertext) == 0); memset(plaintext, 0, DATA_SIZE); assert(aes_crypt_ecb(&aes_dec, AES_DECRYPT, ciphertext, plaintext) == 0); */ // 加密 & 解密. 明文与密文的长度是不固定的, 但必须是16bytes的倍数 const unsigned int DATA_SIZE = 1024; unsigned char plaintext[DATA_SIZE] = { 0 }; unsigned char ciphertext[DATA_SIZE] = { 0 }; sprintf((char*)plaintext, "%s", "return 0 if successful, or POLARSSL_ERR_AES_INVALID_INPUT_LENGTH, assert(aes_crypt_ecb(&aes_dec, AES_DECRYPT, ciphertext, plaintext) == 0);"); const unsigned int IV_SIZE = 16; unsigned char iv[IV_SIZE] = { 0 }; //unsigned char iv2[IV_SIZE] = { 0 }; //ctr_drbg_random(&ctr_drbg, iv, IV_SIZE); //strcpy((char*)iv2, (const char*)iv); assert(aes_crypt_cbc(&aes_enc, AES_ENCRYPT, DATA_SIZE, iv, plaintext, ciphertext) == 0); memset(plaintext, 0, DATA_SIZE); memset(iv, 0, IV_SIZE); assert(aes_crypt_cbc(&aes_dec, AES_DECRYPT, DATA_SIZE, iv, ciphertext, plaintext) == 0); puts("over");}int main(){ goto AES; // RSARSA: rsa r; generate_rsa(r); unsigned char plaintext[] = "moyakukudi"; unsigned char ciphertext[BUFFER_SIZE] = { 0 }; unsigned int ciphertext_len = BUFFER_SIZE; encrypt(r, plaintext, sizeof(plaintext), ciphertext, ciphertext_len); unsigned char output[BUFFER_SIZE] = { 0 }; unsigned int output_len = BUFFER_SIZE; decrypt(r, ciphertext, ciphertext_len, output, output_len); // AESAES: test_aes(); system("pause"); return 0;}