libopenssl 实现私钥加密公钥解密

在需要验证可信来源时,需要用到签名验签。因此,需要使用私钥加密,公钥解密,取得被加密的信息。这就会使用到私钥加密,公钥解密的场景了。

参考:
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_PADDINGRSA_X931_PADDING 。公钥加密,私钥解密,各 padding 方式都是支持的。

运行结果:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值