上周折腾加密与解密,用了openssl, crypto++, polarssl, cyassl, 说起真的让人很沮丧,只有openssl & polarssl两个库的RSA & AES 加密和解密,我用起来了,crypto++各种模板,各种多继承,看的头大,而且对各种常用的加密算法也不了解,所以这个库我在折腾了一天之后就放弃了;cyassl这个库现在没什么印象了;openssl没什么好说的,用起来很方便,尤其是使用win32openssl,都不用自己编译,下载下来安装好了就能用,着实方便;但是我是要在移动终端使用RSA & AES,研究了半天怎么只使用openssl的源代码,发现还真是麻烦;总之呢,现在我决定使用polarssl,接口简单易用,而且使用源代码进行编译,都是C文件,肯定是跨平台的了,很小,很精悍,下面帖出使用polarssl实现的RSA & AES加密和解密的过程,便于日后直接使用

#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"

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;

    // RSA
RSA:
    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);

    // AES
AES:

    test_aes();

    system("pause");
    return 0;
}

https://www.cnblogs.com/emyueguang/p/4072906.html

posted on 2019-06-03 15:24  瓦楞球  阅读(442)  评论(0编辑  收藏  举报