在需要验证可信来源时,需要用到签名验签。因此,需要使用私钥加密,公钥解密,取得被加密的信息。这就会使用到私钥加密,公钥解密的场景了。
参考:
https://github.com/openssl/openssl/issues/20493
https://blog.csdn.net/wq897387/article/details/114129820
使用 openssl-1.1.1 版本,3.x版本API不一样。
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include "openssl/ssl.h"
#include "openssl/pem.h"
#include "openssl/rsa.h"
#include "openssl/bio.h"
#define ENC_PADDING_TYPE RSA_PKCS1_PADDING
int encrypt(uint8_t *data, int len, uint8_t *out)
{
int ret = 0;
uint8_t buff[8192] = {0};
RSA *rsa = NULL;
BIO *bio = NULL;
int len1 = 0;
FILE *f = fopen("private.pem", "r");
if (!f) {
printf("Open private.pem error\n");
return -1;
}
len1 = fread(buff, 1, sizeof(buff), f);
fclose(f);
bio = BIO_new_mem_buf(buff, len1);
if (!bio) {
printf("BIO_new_mem_buf error\n");
return -1;
}
rsa = PEM_read_bio_RSAPrivateKey(bio, &rsa, NULL, NULL);
if (!rsa) {
printf("PEM_read_bio_PrivateKey error\n");
return -1;
}
ret = RSA_private_encrypt(len, data, out, rsa, ENC_PADDING_TYPE);
if (!ret) {
printf("RSA_private_encrypt error\n");
RSA_free(rsa);
BIO_free_all(bio);
return -1;
}
RSA_free(rsa);
BIO_free_all(bio);
return 0;
}
int decrypt(uint8_t *data, uint8_t *out)
{
int ret = 0;
uint8_t buff[8192] = {0};
RSA *rsa = NULL;
BIO *bio = NULL;
FILE *f = fopen("public.pem", "r");
if (!f) {
printf("Open public.pem error\n");
return -1;
}
fread(buff, 1, sizeof(buff), f);
fclose(f);
bio = BIO_new_mem_buf(buff, -1);
if (!bio) {
printf("BIO_new_mem_buf error\n");
return -1;
}
rsa = PEM_read_bio_RSA_PUBKEY(bio, &rsa, NULL, NULL);
if (!rsa) {
printf("PEM_read_bio_RSA_PUBKEY error\n");
return -1;
}
ret = RSA_public_decrypt(256, data, out, rsa, ENC_PADDING_TYPE);
if (!ret) {
printf("RSA_public_decrypt error\n");
RSA_free(rsa);
BIO_free_all(bio);
return -1;
}
RSA_free(rsa);
BIO_free_all(bio);
return 0;
}
int main(int argc, char **argv)
{
const char text[8192] = "Hello world11111111111111111";
uint8_t enc[8192] = {0};
uint8_t dec[8192] = {0};
printf("Text: %s\n", text);
encrypt(text, strlen(text), enc);
decrypt(enc, dec);
printf("Decrypt: %s\n", dec);
return 0;
}
经测试,私钥加密,公钥解密,支持的 padding 方式只有 RSA_PKCS1_PADDING
和 RSA_X931_PADDING
。公钥加密,私钥解密,各 padding 方式都是支持的。文章来源:https://uudwc.com/A/aYDLz
运行结果:
文章来源地址https://uudwc.com/A/aYDLz