使用OpenSSL库接口,实现AES CBC加密,基于X509 base64编码证书的RSA非对称加密例子

    RSA加密的填充方式安全不一样,RSA算法PKCS1填充方式没有OAEP填充方式安全;同样的AES选择CBC模式更加安全。

    网上看了好多例子,都没有使用X509 base64编码证书的RSA OAEP填充方式加密。研究记录下RSA、AES的加密,以供参考。话不多说,直接上demo。

/*******************************************************************
*    HISTORY: RSA、AES demo by hyy
*    DATE:    2021-04-01
*******************************************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <openssl/sha.h>
#include <openssl/aes.h>
#include <openssl/bio.h>
#include <openssl/ssl.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>

#define FREE(__n) \
    if (__n) \
    { \
        free(__n); \
        __n = NULL; \
    }

/* base64加密; outlen >= ((inlen + 2) / 3 * 4 + ((inlen + 2) / 3 * 4 + 63) / 64) */
static int base64_encode(const char *in, int inlen, char *out, int *outlen, unsigned char newline)
{
    BIO     *bmem = NULL;
    BIO     *b64  = NULL;
    BUF_MEM *bptr = NULL;

    b64  = BIO_new(BIO_f_base64());
    bmem = BIO_new(BIO_s_mem());

    if (!b64 || !bmem)
    {
        printf("fail to BIO_new\n");
        return -1;
    }
    b64  = BIO_push(b64, bmem);
    if (!newline)
    {
        BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
    }
    *outlen = BIO_write(b64, in, inlen);
    if (*outlen <= 0 || *outlen != inlen)
    {
        printf("fail to BIO_write\n");
        return -1;
    }
    BIO_flush(b64);
    BIO_get_mem_ptr(b64, &bptr);

    *outlen = bptr->length;
    memcpy(out, bptr->data, *outlen);

    BIO_free_all(b64);

    return 0;
}

/* base64解密 */
static int base64_decode(const char *in, int inlen, char *out, int *outlen, unsigned char newline)
{
    BIO *b64  = NULL;
    BIO *bio  = NULL;

    b64 = BIO_new(BIO_f_base64());
    bio = BIO_new_mem_buf((void *)in, inlen);

    if (!b64 || !bio)
    {
        printf("fail to BIO_new\n");
        return -1;
    }
    bio = BIO_push(b64, bio);
    if (!newline)
    {
        BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
    }

    *outlen = BIO_read(bio, out, inlen);
    if (*outlen <= 0)
    {
        printf("fail to BIO_write\n");
        return -1;
    }
    BIO_free_all(bio);

    return 0;
}

static void get_sha256_func(const char *str, unsigned char hash[SHA256_DIGEST_LENGTH])
{
    unsigned char *sha = SHA256(str, strlen(str), 0);

    if (sha)
    {
        memcpy(hash, sha, SHA256_DIGEST_LENGTH);
    }
}

static void get_sha256_func2(const char *str, unsigned char hash[SHA256_DIGEST_LENGTH])
{
    SHA256_CTX    sha256;

    SHA256_Init(&sha256);
    SHA256_Update(&sha256, str, strlen(str));
    SHA256_Final(hash, &sha256);
}

/*
 * 注意以下,一不小心得多花时间排查问题:
 * 1、加解密设置的key接口不同
 * 2、AES_cbc_encrypt的加密码参数AES_ENCRYPT和 AES_DECRYPT也是不一样
 * 3、AES_cbc_encrypt的参数length是指输入的大小,要准确否则加解密结果会不准确
 */
static int aes256_cbc_encrypt(const unsigned char *in, unsigned char *out, size_t len)
{
    unsigned char c_key[SHA256_DIGEST_LENGTH] = {0};
    unsigned char iv[AES_BLOCK_SIZE]          = {0};
    AES_KEY       aes_key;

    get_sha256_func("202103181810", c_key);

    if (AES_set_encrypt_key((unsigned char*)c_key, SHA256_DIGEST_LENGTH * 8, &aes_key) < 0)
  
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值