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)