openssl的计算MD5、AES、RSA

1.MD5
主要由以下几个函数计算:MD5、MD5_Init、MD5_Update、MD5_Final

#include <openssl/md5.h>
#include <openssl/err.h>
//1.计算字符串
    unsigned char MD5result[128]={0};
    unsigned char  inStr[4]={'1','2','3','4'} ;
    size_t inStrSize=sizeof(inStr);
    MD5(inStr,inStrSize,MD5result); //获取字符串的MD5值
//2.计算文件
    unsigned char MD5result[128]={0};
    MD5_CTX md5_ctx;
    MD5_Init(&md5_ctx);
    char readData[2048]={0};
    while(!rfile.eof())
    {
        rfile.read(ReadBuff,sizeof(readBuff));   //以二进制方式读需要计算MD5的文件
        int rlength = rfile.gcount();
        if(rlength>0)
        {
            MD5_Update(&md5_ctx,readBuff,rlength); //将当前文件块加入,并更新MD5
        }
    }
    MD5_Final(MD5result,&md5_ctx);  //获取MD5值

2.AES

AES加密最常用ECB、CBC分组模式,以ECB模式128位加密zeropadding为例:

//userkey:用户指定的密码,可以通过MD5、sha等算法生成,也可以用户自定义(注意:密码长度只能是16、24、32字节,如果密码字符串长度不够,可以在字符串末尾追加一些特定的字符,或者重复密码字符串,直到满足最少的长度。)

#include <openssl/aes.h>
#include <openssl/evp.h>

//1.加密
int aes128_ecb_encrypt_zeropadding_evp(const unsigned char *userkey,int userkey_len, const unsigned char* plaintext,int plaintext_len, unsigned char *out_ciphetext)
{
  if (    userkey_len<=0||
            (!(userkey_len == 16 ||userkey_len== 24 ||userkey_len == 32))
        )
    {
     
        return -1;
    }

    const unsigned char *data = plaintext;
    unsigned char *encrypt =out_ciphetext;
    const unsigned char *input_gen_key =userkey;

    unsigned char iv[EVP_MAX_IV_LENGTH] = {0}; ecb模式不需要iv偏移量
    memset((void *)iv, 'i', EVP_MAX_IV_LENGTH);
    EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
    int ret = 0;
    int tlen = 0;
    int mlen = 0;
    int flen = 0;

    /*初始化ctx*/
    EVP_CIPHER_CTX_init(ctx);

    /*指定加密算法及key和iv(此处IV没有用)*/
    ret = EVP_EncryptInit_ex(ctx, EVP_aes_128_ecb(), NULL, input_gen_key, iv);
    if (ret != 1)
    {
        printf("EVP_EncryptInit_ex failed\n");
        EVP_CIPHER_CTX_free(ctx);
        return -1;
    }

    /*禁用padding功能*/
    //EVP_CIPHER_CTX_set_padding(ctx, 0);
    /*进行加密操作*/
    ret = EVP_EncryptUpdate(ctx, encrypt, &mlen, data, plaintext_len);
    if (ret != 1)
    {
        printf("EVP_EncryptUpdate failed\n");
        EVP_CIPHER_CTX_free(ctx);
        return -1;
    }
    /*结束加密操作*/
    ret = EVP_EncryptFinal_ex(ctx, encrypt + mlen, &flen);
    if (ret != 1)
    {
        printf("EVP_EncryptFinal_ex failed\n");
        return -1;
    }

    EVP_CIPHER_CTX_free(ctx);
    return mlen + flen;
}
//2.AES解密
int AES128_ecb_decrypt_zeropadding_evp(const unsigned char *userkey,int userkey_len, const unsigned char*in_ciphetext,int in_ciphetext_len, unsigned char*out_plaintext)
{
    if (    userkey_len<=0||
            (!(userkey_len == 16 ||userkey_len== 24 ||userkey_len == 32))
        )
    {
     
        return -1;
    }

    const unsigned char *data =in_ciphetext;
    unsigned char *decrypt =out_plaintext;
    const unsigned char *input_gen_key =userkey;
    if (NULL == decrypt || NULL == data || NULL == input_gen_key)
    {
        return -1;
    }

    unsigned char iv[EVP_MAX_IV_LENGTH] = {0}; ecb模式不需要iv偏移量
    memset((void *)iv, 'i', EVP_MAX_IV_LENGTH);
    EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
    int ret = 0;
    int tlen = 0;
    int mlen = 0;
    int flen = 0;
    EVP_CIPHER_CTX_init(ctx);
    ret = EVP_DecryptInit_ex(ctx, EVP_aes_128_ecb(), NULL, input_gen_key, iv);
    if (ret != 1)
    {
        printf("EVP_DecryptInit_ex failed\n");
        EVP_CIPHER_CTX_free(ctx);
        return -1;
    }
    /*禁用padding功能*/
    //EVP_CIPHER_CTX_set_padding(ctx, 0);
    ret = EVP_DecryptUpdate(ctx, decrypt, &mlen, data, in_ciphetext_len);
    if (ret != 1)
    {
        printf("EVP_DecryptUpdate failed\n");
        EVP_CIPHER_CTX_free(ctx);
        return -1;
    }
    ret = EVP_DecryptFinal_ex(ctx, decrypt + mlen, &flen);
    if (ret != 1)
    {
        printf("EVP_DecryptFinal_ex failed\n");
    }
    EVP_CIPHER_CTX_free(ctx);
    return mlen + flen;
}

3.RSA

以RSA512 padding为例,包括秘钥生成(PKCS#1/PKCS#8)、秘钥加载、加密解密
在这里插入图片描述

#include <openssl/evp.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>
/*********************
 * 
 * rsa的PKCS#1密钥头为‘-----BEGIN RSA PUBLIC KEY-----’,
 * rsa的PKCS#8密钥头为‘-----BEGIN PUBLIC KEY-----’
 * 对PKCS#1格式的密钥加载使用PEM_read_RSAPublicKey()函数
 * 对PKCS#8格式公钥的加载使用PEM_read_RSA_PUBKEY()函数
 * 
 * *********************/
int gen_pem_rsa512_pkcs1_pub_prvkey(const char *dir_path)
{
    if (NULL == dir_path)
    {
        return -1;
    }
    int ret = -1;
    RSA *rsa_key = RSA_new();
    BIGNUM *bignum_t = BN_new();
    int bits = 512;
    FILE *prv_key_file = NULL;
    FILE *pub_key_file = NULL;
    char prv_key_path[512] = {0};
    char pub_key_path[512] = {0};
    snprintf(prv_key_path, sizeof(prv_key_path) - 1, "%s/myprv_pkcs1.pem", dir_path);
    snprintf(pub_key_path, sizeof(pub_key_path) - 1, "%s/mypub_pkcs1.pem", dir_path);
    prv_key_file = fopen(prv_key_path, "wb");
    pub_key_file = fopen(pub_key_path, "wb");

    if (NULL == rsa_key || NULL == bignum_t || NULL == prv_key_file || NULL == pub_key_file)
    {
        goto clear_gen_pem_rsa512_pkcs1_pub_prvkey;
    }
    BN_set_word(bignum_t, 65537);
    if (1 != RSA_generate_key_ex(rsa_key, bits, bignum_t, NULL))
    {
        goto clear_gen_pem_rsa512_pkcs1_pub_prvkey;
    }
    if (1 != PEM_write_RSAPrivateKey(prv_key_file, rsa_key, NULL, NULL, 0, NULL, NULL))
    {
        goto clear_gen_pem_rsa512_pkcs1_pub_prvkey;
    }
    if (1 != PEM_write_RSAPublicKey(pub_key_file, rsa_key))
    {
        goto clear_gen_pem_rsa512_pkcs1_pub_prvkey;
    }
    ret = 0;
    goto clear_gen_pem_rsa512_pkcs1_pub_prvkey;
clear_gen_pem_rsa512_pkcs1_pub_prvkey:
    if (rsa_key)
        RSA_free(rsa_key);
    if (bignum_t)
        BN_free(bignum_t);
    if (prv_key_file)
        fclose(prv_key_file);
    if (pub_key_file)
        fclose(pub_key_file);
    return ret;
}

int gen_pem_rsa512_pkcs8_pub_prvKey(const char *dir_path)
{
    if (NULL == dir_path)
    {
        return -1;
    }
    int ret = -1;
    RSA *rsa_key = RSA_new();
    BIGNUM *bignum_t = BN_new();
    EVP_PKEY *evpkey = EVP_PKEY_new();
    int bits = 512;
    FILE *prv_key_file = NULL;
    FILE *pub_key_file = NULL;
    char prv_key_path[512] = {0};
    char pub_key_path[512] = {0};
    snprintf(prv_key_path, sizeof(prv_key_path) - 1, "%s/myprv_pkcs8.pem", dir_path);
    snprintf(pub_key_path, sizeof(pub_key_path) - 1, "%s/mypub_pkcs8.pem", dir_path);
    prv_key_file = fopen(prv_key_path, "wb");
    pub_key_file = fopen(pub_key_path, "wb");

    if (NULL == rsa_key || NULL == bignum_t || NULL == prv_key_file || NULL == pub_key_file || NULL == evpkey)
    {
        goto clear_gen_pem_rsa512_pkcs8_pub_prvKey;
    }
    BN_set_word(bignum_t, 65537);
    if (1 != RSA_generate_key_ex(rsa_key, bits, bignum_t, NULL))
    {
        goto clear_gen_pem_rsa512_pkcs8_pub_prvKey;
    }
    if (1 != EVP_PKEY_set1_RSA(evpkey, rsa_key))
    {
        goto clear_gen_pem_rsa512_pkcs8_pub_prvKey;
    }
    if (1 != PEM_write_PrivateKey(prv_key_file, evpkey, NULL, NULL, 0, NULL, NULL))
    {
        goto clear_gen_pem_rsa512_pkcs8_pub_prvKey;
    }
    if (1 != PEM_write_PUBKEY(pub_key_file, evpkey))
    {
        goto clear_gen_pem_rsa512_pkcs8_pub_prvKey;
    }
    ret = 0;
    goto clear_gen_pem_rsa512_pkcs8_pub_prvKey;

clear_gen_pem_rsa512_pkcs8_pub_prvKey:
    if (rsa_key)
        RSA_free(rsa_key);
    if (bignum_t)
        BN_free(bignum_t);
    if (evpkey)
        EVP_PKEY_free(evpkey);
    if (prv_key_file)
        fclose(prv_key_file);
    if (pub_key_file)
        fclose(pub_key_file);
    return ret;
}
int read_pubkey_pem_rsa512_pkcs1(const char *key_path, RSA **out_rsa)
{
    if (NULL == key_path)
    {
        return -1;
    }
    FILE *pf_key = NULL;
    pf_key = fopen(key_path, "rb");
    if (NULL == pf_key)
    {
        return -1;
    }
    *out_rsa = RSA_new();
    if (NULL == out_rsa)
    {
        fclose(pf_key);
        return -1;
    }
    *out_rsa = PEM_read_RSAPublicKey(pf_key, out_rsa, NULL, NULL);
    fclose(pf_key);
    return 0;
}

int read_pubkey_pem_rsa512_pkcs8(const char *key_path, RSA **out_rsa)
{
    if (NULL == key_path)
    {
        return -1;
    }
    FILE *pf_key = NULL;
    pf_key = fopen(key_path, "rb");
    if (NULL == pf_key)
    {
        return -1;
    }

    EVP_PKEY* rsa_evp=NULL;
    rsa_evp= PEM_read_PUBKEY(pf_key, &rsa_evp, NULL, NULL);
    *out_rsa = EVP_PKEY_get1_RSA(rsa_evp);
    //RSA_print_fp(stdout, *out_rsa, 0);
    EVP_PKEY_free(rsa_evp);
    fclose(pf_key);
    return 0;
}
int read_prvkey_pem_rsa512_pkcs1(const char *key_path, RSA **out_rsa)
{
    if (NULL == key_path)
    {
        return -1;
    }
    FILE *pf_key = NULL;
    pf_key = fopen(key_path, "rb");
    if (NULL == pf_key)
    {
        return -1;
    }
    *out_rsa = RSA_new();
    if (NULL == out_rsa)
    {
        fclose(pf_key);
        return -1;
    }
    *out_rsa = PEM_read_RSAPrivateKey(pf_key, out_rsa, NULL, NULL);
    //RSA_print_fp(stdout, *out_rsa, 0);
    fclose(pf_key);
    return 0;
}
int read_prvkey_pem_rsa512_pkcs8(const char *key_path, RSA **out_rsa)
{
    if (NULL == key_path)
    {
        return -1;
    }
    FILE *pf_key = NULL;
    pf_key = fopen(key_path, "rb");
    if (NULL == pf_key)
    {
        return -1;
    }

    EVP_PKEY *rsa_evp=NULL;
    rsa_evp= PEM_read_PrivateKey(pf_key, &rsa_evp, NULL, NULL);
    *out_rsa = EVP_PKEY_get1_RSA(rsa_evp);
    //RSA_print_fp(stdout, *out_rsa, 0);
    EVP_PKEY_free(rsa_evp);
    fclose(pf_key);
    return 0;
}

int pub_encrypt_rsa512_pkcs1_padding(unsigned char *in_data, size_t input_len, unsigned char *out_data, size_t *out_len, RSA *rsa_key)
{
    size_t total_len=0;
    size_t loop=input_len/64;
    for(int i=0;i<loop;i++)
    {
        size_t len=0;
        len=RSA_public_encrypt(64,(in_data+i*64), out_data+total_len, rsa_key, RSA_PKCS1_PADDING);
        total_len+=len;
    }
    size_t final_len=0;
    final_len=RSA_public_encrypt(input_len%64,in_data+loop*64, out_data+total_len, rsa_key, RSA_PKCS1_PADDING);
    total_len=total_len+final_len;
    *out_len=total_len;

    return 0;
}

int pub_decrypt_rsa512_pkcs1_padding(unsigned char *in_data, size_t input_len, unsigned char *out_data, size_t *out_len, RSA *rsa_key)
{
    //RSA_print_fp(stdout, rsa_key, 0);
    size_t total_len=0;
    size_t loop=input_len/64;
    for(int i=0;i<loop;i++)
    {
        size_t len=0;
        len=RSA_public_decrypt(64,(in_data+i*64), out_data+total_len, rsa_key, RSA_PKCS1_PADDING);
        total_len+=len;
    }
    *out_len=total_len;
    return 0;
}

int prv_encrypt_rsa512_pkcs1_padding(unsigned char *in_data, size_t input_len, unsigned char *out_data, size_t *out_len, RSA *rsa_key)
{
    size_t total_len=0;
    size_t loop=input_len/64;
    for(int i=0;i<loop;i++)
    {
        size_t len=0;
        len=RSA_private_encrypt(64,(in_data+i*64), out_data+total_len, rsa_key, RSA_PKCS1_PADDING);
        total_len+=len;
    }
    size_t final_len=0;
    final_len=RSA_private_encrypt(input_len%64,in_data+loop*64, out_data+total_len, rsa_key, RSA_PKCS1_PADDING);
    total_len=total_len+final_len;
    *out_len=total_len;
    return 0;
}
int prv_decrypt_rsa512_pkcs1_padding(unsigned char *in_data, size_t input_len, unsigned char *out_data, size_t *out_len, RSA *rsa_key)
{

    //RSA_print_fp(stdout, rsa_key, 0);
    size_t total_len=0;
    size_t loop=input_len/64;
    for(int i=0;i<loop;i++)
    {
        size_t len=0;
        len=RSA_private_decrypt(64,(in_data+i*64), out_data+total_len, rsa_key, RSA_PKCS1_PADDING);
        total_len+=len;
    }
    *out_len=total_len;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值