最近有个项目需要用到rsa加密和解密,平台是cortex-m4单片机,于是我想用炒的比较火的mbedtls库实现。既然这玩意炒的比较火,资料应该不少才对,上手以后才发现资料少的可怜,仅有的资料基本都是在注水,参考意义不大,pem格式的秘钥操作这一块基本相当于没有资料,只能自己硬着头皮搞了。搞了两天以后终于搞出来了。

关于pem相关知识这里不做介绍,我就直接贴代码。

#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
#include <stdio.h>
#include <stdlib.h>
#define mbedtls_printf       printf
#define mbedtls_exit         exit
#define MBEDTLS_EXIT_SUCCESS EXIT_SUCCESS
#define MBEDTLS_EXIT_FAILURE EXIT_FAILURE
#endif /* MBEDTLS_PLATFORM_C */#include "mbedtls/rsa.h"
#include "mbedtls/entropy.h"
#include "mbedtls/ctr_drbg.h"
#include "mbedtls/pk.h"
#include <stdio.h>
#include <string.h>int rsa_encrypt()
{FILE* f = NULL;long size;size_t n;unsigned char* publickey = NULL;mbedtls_pk_context ctx_pk;/*********************************************/int ret = 1;size_t i;mbedtls_rsa_context rsa;mbedtls_entropy_context entropy;mbedtls_ctr_drbg_context ctr_drbg;unsigned char input[1024];unsigned char buf[512];const char* pers = "rsa_encrypt";mbedtls_mpi N, E;       //定义一个大数,也就是公钥
/*****************************************************/mbedtls_pk_init(&ctx_pk);if ((f = fopen("rsa4096_pub.pem", "rb")) == NULL)      //打开pem格式的公钥文件{mbedtls_printf("\n  .  Open public key file failed!");return(-1);}fseek(f, 0, SEEK_END);if ((size = ftell(f)) == -1){fclose(f);return(-1);}fseek(f, 0, SEEK_SET);n = (size_t)size;    //if (n + 1 == 0 || (publickey = mbedtls_calloc(1, n + 1)) == NULL){fclose(f);return(-1);}if (fread(publickey, 1, n, f) != n){fclose(f);free(publickey);publickey = NULL;return(-1);}fclose(f);/*从pem文件里获得公钥*/if (0 != mbedtls_pk_parse_public_key(&ctx_pk, publickey, n + 1)){mbedtls_printf("\n  . Can't import public key");}else{mbedtls_printf("\n  . Import public key successfully");}free(publickey);publickey = NULL;/*****************************************************************/mbedtls_printf("\n  . Seeding the random number generator...");memset(input, 0, 1024);fflush(stdout);mbedtls_mpi_init(&N);mbedtls_mpi_init(&E);mbedtls_rsa_init(&rsa, MBEDTLS_RSA_PKCS_V15, 0);mbedtls_ctr_drbg_init(&ctr_drbg);      //初始化ctr drbg结构体,用于随机数的生成mbedtls_entropy_init(&entropy);       //初始化熵源ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, (const unsigned char*)pers, strlen(pers));     //生成随机数if (ret != 0){mbedtls_printf(" failed\n  ! mbedtls_ctr_drbg_seed returned %d\n", ret);goto exit;}/*导入pem内的公钥*/rsa = *(mbedtls_rsa_context*)ctx_pk.pk_ctx;      input[0] = 'H';input[1] = 'E';input[2] = 'L';input[3] = 'L';input[4] = 'O';input[5] = ',';input[6] = 'W';input[7] = 'O';input[8] = 'R';input[9] = 'L';input[10] = 'D';input[11] = '!';input[12] = '\0';/** Calculate the RSA encryption of the hash.*/mbedtls_printf("\n  . Generating the RSA encrypted value");fflush(stdout);/*加密操作,利用公钥加密*/ret = mbedtls_rsa_pkcs1_encrypt(&rsa, mbedtls_ctr_drbg_random, &ctr_drbg, MBEDTLS_RSA_PUBLIC, 12, input, buf);if (ret != 0){mbedtls_printf(" failed\n  ! mbedtls_rsa_pkcs1_encrypt returned %d\n\n", ret);goto exit;}/** Write the signature into result-enc.txt*/if ((f = fopen("result-enc.txt", "wb+")) == NULL)      //将加密文件写入到result-enc.txt{mbedtls_printf(" failed\n  ! Could not create %s\n\n", "result-enc.txt");goto exit;}for (i = 0; i < rsa.len; i++){mbedtls_fprintf(f, "%02X%s", buf[i], (i + 1) % 16 == 0 ? "\r\n" : " ");}fclose(f);mbedtls_printf("\n  . Done (created \"%s\")\n\n", "result-enc.txt");  exit:/*释放资源*/mbedtls_mpi_free(&N);mbedtls_mpi_free(&E);mbedtls_ctr_drbg_free(&ctr_drbg);mbedtls_entropy_free(&entropy);mbedtls_rsa_free(&rsa);return 0;
}int rsa_decrypt()
{FILE* f = NULL;long size;size_t n;unsigned char* privatekey = NULL;mbedtls_pk_context ctx_pk;/*******************************/int ret = 1;int c;size_t i;mbedtls_rsa_context rsa;mbedtls_mpi N, P, Q, D, E, DP, DQ, QP;      //定义大数mbedtls_entropy_context entropy;mbedtls_ctr_drbg_context ctr_drbg;unsigned char result[1024];unsigned char buf[512];const char* pers = "rsa_decrypt";memset(result, 0, sizeof(result));/*********************************/mbedtls_pk_init(&ctx_pk);if ((f = fopen("rsa4096_prv.pem", "rb")) == NULL)      //打开pem格式的公钥文件{mbedtls_printf("\n  . Open private key file failed!");return(-1);}fseek(f, 0, SEEK_END);if ((size = ftell(f)) == -1){fclose(f);return(-1);}fseek(f, 0, SEEK_SET);n = (size_t)size;    //if (n + 1 == 0 || (privatekey = mbedtls_calloc(1, n + 1)) == NULL){fclose(f);return(-1);}if (fread(privatekey, 1, n, f) != n){fclose(f);free(privatekey);privatekey = NULL;return(-1);}fclose(f);/*从pem文件里获得私钥*/if (0 != mbedtls_pk_parse_key(&ctx_pk, privatekey, n + 1, NULL, 0)){mbedtls_printf("\n  . Can't import private key");}else{mbedtls_printf("\n  . Import private key successfully");}free(privatekey);privatekey = NULL;mbedtls_printf("\n  . Seeding the random number generator...");fflush(stdout);mbedtls_rsa_init(&rsa, MBEDTLS_RSA_PKCS_V15, 0);mbedtls_ctr_drbg_init(&ctr_drbg);mbedtls_entropy_init(&entropy);mbedtls_mpi_init(&N);mbedtls_mpi_init(&P);mbedtls_mpi_init(&Q);mbedtls_mpi_init(&D);mbedtls_mpi_init(&E);mbedtls_mpi_init(&DP);mbedtls_mpi_init(&DQ);mbedtls_mpi_init(&QP);ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func,&entropy, (const unsigned char*)pers,strlen(pers));if (ret != 0){mbedtls_printf(" failed\n  ! mbedtls_ctr_drbg_seed returned %d\n",ret);goto exit;}/*导入pem内的私钥*/rsa = *(mbedtls_rsa_context*)ctx_pk.pk_ctx;if ((ret = mbedtls_rsa_complete(&rsa)) != 0){mbedtls_printf(" failed\n  ! mbedtls_rsa_complete returned %d\n\n", ret);goto exit;}/** Extract the RSA encrypted value from the text file*/if ((f = fopen("result-enc.txt", "rb")) == NULL){mbedtls_printf("\n  ! Could not open %s\n\n", "result-enc.txt");goto exit;}i = 0;while (fscanf(f, "%02X", &c) > 0 && i < (int)sizeof(buf))buf[i++] = (unsigned char)c;fclose(f);if (i != rsa.len){mbedtls_printf("\n  ! Invalid RSA signature format\n\n");goto exit;}/** Decrypt the encrypted RSA data and print the result.*/mbedtls_printf("\n  . Decrypting the encrypted data");fflush(stdout);ret = mbedtls_rsa_pkcs1_decrypt(&rsa, mbedtls_ctr_drbg_random, &ctr_drbg, MBEDTLS_RSA_PRIVATE, &i, buf, result, 1024);if (ret != 0){mbedtls_printf(" failed\n  ! mbedtls_rsa_pkcs1_decrypt returned %d\n\n", ret);      goto exit;}mbedtls_printf("\n  . OK\n\n");mbedtls_printf("The decrypted result is: '%s'\n\n", result);exit:mbedtls_ctr_drbg_free(&ctr_drbg);mbedtls_entropy_free(&entropy);mbedtls_rsa_free(&rsa);mbedtls_mpi_free(&N);mbedtls_mpi_free(&P);mbedtls_mpi_free(&Q);mbedtls_mpi_free(&D); mbedtls_mpi_free(&E);mbedtls_mpi_free(&DP);mbedtls_mpi_free(&DQ);mbedtls_mpi_free(&QP);return 0;}
int main()
{int exit_code = 0;rsa_encrypt();     //加密rsa_decrypt();     //解密#if defined(_WIN32)mbedtls_printf("  + Press Enter to exit this program.\n");fflush(stdout); getchar();
#endifreturn(exit_code);
}

mbedtls库:https://github.com/ARMmbed/mbedtls

开发环境:visual studio 2019

ps:我使用的公钥和私钥的在tests/data_files内,也可以使用自己生成的

2021.02.03补充宏定义

/* System support */
#define MBEDTLS_PLATFORM_C                       //启用平台抽象接口,重新定义printf,sprintf 和malloc,free
#define MBEDTLS_PLATFORM_MEMORY                  //启用内存分配接口,需要自己实现malloc,free
//#define MBEDTLS_MEMORY_BUFFER_ALLOC_C          //启用mbedtls自带的内存分配接口,适用于没有动态内存分配的平台
#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS        //不使用标准的库函数,如malloc,free
//#define MBEDTLS_PLATFORM_EXIT_ALT              //允许使用平台exit接口
#define MBEDTLS_NO_PLATFORM_ENTROPY              //不使用内置熵源,需要自己实现熵 ,不定义该宏,使用内置熵,只有window和linux才可以注释掉,其他平台不支持内置熵
#define MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES       //取消默认熵,不定义该宏,就会使用默认熵
#define MBEDTLS_PLATFORM_PRINTF_ALT              //使能printf替换
#define MBEDTLS_PLATFORM_SNPRINTF_ALT            //使能sprintf替换#define MBEDTLS_AES_C        //AES
#define MBEDTLS_SHA256_C     //SHA256
#define MBEDTLS_ENTROPY_C    //使能熵源
#define MBEDTLS_CTR_DRBG_C   //随机数模块
#define MBEDTLS_BIGNUM_C     //大数模块
//#define MBEDTLS_GENPRIME     //使能素数生成,如果生成RSA的公钥和私钥需要定义此宏
#define MBEDTLS_MD_C         //使能MD通用接口,计算消息摘要
#define MBEDTLS_OID_C        //必须定义
#define MBEDTLS_RSA_C        //RSA
#define MBEDTLS_PKCS1_V15    //RSA填充方案
//#define MBEDTLS_RSA_NO_CRT    //是否通过中国剩余定理加速
#define MBEDTLS_AES_ROM_TABLES    //预定义s盒,可节约部分内存空间#define MBEDTLS_ERROR_C        //错误代码解析
#define MBEDTLS_BASE64_C       //使能Base64编码
//#define MBEDTLS_SHA256_SMALLER
#define MBEDTLS_FS_IO        //txt格式的秘钥文件
/*pem格式秘钥需要定义的宏*/
#define MBEDTLS_PK_PARSE_C
#define MBEDTLS_PK_C
#define MBEDTLS_ASN1_PARSE_C
#define MBEDTLS_PEM_PARSE_C

mbedtls rsa使用pem文件相关推荐

  1. RSA解密-提供enc和pem文件类

    RSA解密 --提供enc和pem文件类 解压文件包发现两个文件,flag.enc和pub.pem两个文件.首先我们会想到openssl.这类题目需要用linux的openssl来解.openssl是 ...

  2. (PKCS1) RSA 公私钥 pem 文件 提取 公私钥 e d 和 模数 n

    参考链接:RSA公钥文件(PEM)解析 参考链接:OPENSSL中RSA私钥文件(PEM格式)解析[一] 参考:使用openssl命令剖析RSA私钥文件格式 RSA PKCS8 与 PKCS1 公私钥 ...

  3. 使用Java代码生成RSA公私钥的.pem文件

    大家好,我是神韵,是一个技术&生活博主.出文章目的主要是两个,一是好记忆不如烂笔头,记录总结中提高自己.二是希望我的文章可以帮到大家.欢迎大家留言讨论,你们的行动将是我无限的动力. 本篇主题是 ...

  4. 妙借Git自带的OpenSSL生成RSA公私钥的.pem 文件

    大家好,我是神韵,是一个技术&生活博主.出文章目的主要是两个,一是好记忆不如烂笔头,记录总结中提高自己.二是希望我的文章可以帮到大家.欢迎来点赞打卡,你们的行动将是我无限的动力. 本篇主题是: ...

  5. 如何使用puttygen基于pem文件生成可供登录的ppk文件

    putty默认不支持用私钥文件pem远程登录,需要先用puttygen转换成ppk文件. 选择RSA加密: 点load按钮加载本地的pem文件: 点OK: 忽略save the key without ...

  6. 证书.p12导出 与 xxx.p1文件转出私钥,公钥,xxxx.crt文件,xxx.cre文件, xxx.pem文件

    首先:会有一个 xxxx.p12文件. p12文件是我们的每一个证书都可以生成一个.p12文件,这个文件是一个加密的文件,只要知道其密码,就可以供给所有的mac设备使用,使设备不需要在苹果开发者网站重 ...

  7. ssl证书生成pem文件

    一般通过FreeSSL生成的证书(nginx下)是chain.crt和key.key格式, 而Nginx或者其他SSL服务加载为pem格式,现转换方法如下: 第一步: mkdir /etc/ssl/c ...

  8. 生成pfx文件需要在服务器上执行,PEM文件和private.key文件生成IIS服务器所需的pfx文件(配置SSL用)...

    第一步:输入域名,点击"创建免费的SSL证书"按钮,如图 第二步:输入邮箱,点击创建,如图 创建成功后,需要进行dns验证,结果图如下: 第三步:在域名所在的云服务器上,添加域名解 ...

  9. 微信支付商户证书cert.zip中缺少rootca.pem文件解决方法

    要设置微信支付功能,按照操作手册,进行到API证书下载,解压cert.zip后,文件夹中没有rootca.pem文件,什么原因?该怎么处理? 微信支付在配置过程中少不了要做API证书配置,不管是单独上 ...

最新文章

  1. 银行不能成为外国资本的“***”
  2. Python字节到大整数的打包与解包
  3. SSD框架训练自己的数据集
  4. java public object_Java_Object
  5. duration java_Java Duration类| 带示例的dividBy()方法
  6. 为什么python的命名不能以数字开头_python变量不能以数字打头
  7. java 线程池的原理与实现_Java线程池原理及实现
  8. 机械硬盘的SMR与PMR 的概念
  9. js 彻底理解回调函数
  10. Latex beamer 常用操作记录
  11. 如何在功能、特点、价格和性能方面选择PDF编辑器?
  12. SSL证书是要怎么部署的,SSL证书怎么安装你知道吗?
  13. C盘爆满上热搜,简单几招释放几十G空间,一下子就不红了
  14. bigemap批量添加第三方在线地图浏览
  15. WWW相关概念的学习
  16. css水平垂直居中四种常用方式
  17. 学习GAN必须阅读的10篇论文
  18. leetcode13——步长k的差值小于t的元素组,包含1的正方形面积,完全二叉树的结点个数,矩形重叠面积,汇总区间
  19. 第一章 简介(待续)
  20. PSINS源码test_SINS_DR解析

热门文章

  1. C语言中itoa和atoi函数的用法
  2. c语言循环题兔子第三个月生,C语言上机习题
  3. 《Kubernetes知识篇:基于Pod进行资源配额管理》
  4. Zabbix 4.4 web前端界面操作流程:创建主机>创建触发器>报警媒介>动作>邮件 发送/接收 预警信息 等详细操作
  5. M1 ARM版miniforge安装与移除TensorFlow和pytorch环境
  6. Android权限 权限等级 普通权限 敏感权限 申请权限
  7. Python OpenCV开发MR智能人脸识别打卡系统(一、需求分析与系统设计)
  8. TICKScript简介
  9. TeamTalk安装部署手册
  10. JAVA 多用户商城系统b2b2c-Spring Cloud Stream 介绍