码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • libopenssl 实现私钥加密公钥解密


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

    参考:
    https://github.com/openssl/openssl/issues/20493
    https://blog.csdn.net/wq897387/article/details/114129820

    使用 openssl-1.1.1 版本,3.x版本API不一样。

    #include 
    #include 
    #include 
    #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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106

    经测试,私钥加密,公钥解密,支持的 padding 方式只有 RSA_PKCS1_PADDING 和 RSA_X931_PADDING 。公钥加密,私钥解密,各 padding 方式都是支持的。

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

  • 相关阅读:
    SpringCloud(六) - RabbitMQ安装,三种消息发送模式,消息发送确认,消息消费确认(自动,手动)
    一文详解数据链路相关技术
    Selenium特殊场景问题汇总
    IDEA快捷键
    神经网络权重是什么意思,神经网络权重调整方法
    欧洲云巨头OVHcloud收购边缘计算专家 gridscale
    OCP-042之:Oracle实例管理
    CTF 全讲解:[SWPUCTF 2022 新生赛]webdog1__start
    LeetCode程序员面试金典(第 6 版)上
    【MySQL从入门到精通】【高级篇】(六)MySQL表的存储引擎,InnoDB与MyISAM的对比
  • 原文地址:https://blog.csdn.net/duapple/article/details/133150984
  • 最新文章
  • 沪漂五周年了:我越来越迷茫了
    Agentic Skill Routing 实战:别再把所有 Skill 塞进 AI Agent 上下文
    MySQL-Seconds_behind_master的精度误差
    [MAF预定义ChatClient中间件-03]CachingChatClient——利用缓存省钱省时间
    AI的至暗历史:从万众期待到被政府撤资,AI的两次死亡徘徊
    Agent OS :五种驯服不确定性的范式
    PortSwigger SQL注入LAB11
    数据库即时编译JIT
    [Begin]AI Learn Data Day 0
    深度学习进阶(二十七)现代 LLM 的核心架构设计其二:SwiGLU
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
小工具 小游戏
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1

京公网安备 11010502049817号