【网络安全】使用mbedtls 实现 RSA 签名、验签、加密、解密

简介

mbedtls(前身是 PolarSSL)是一个开源、轻量级的 SSL/TLS 库,专为嵌入式系统和资源受限环境设计。

RSA是一种广泛应用的非对称加密算法,是公开密钥密码体制(Public Key Cryptosystem)的一个典型代表,它的核心特点是采用一对密钥,分别是公开密钥(Public Key)和私有密钥(Private Key)。
相关头文件

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "mbedtls/rsa.h"
#include "mbedtls/sha1.h"
#include "mbedtls/pem.h"
#include "mbedtls/ssl.h"
#include "mbedtls/pk.h"
#include "mbedtls/entropy.h"
#include "mbedtls/ctr_drbg.h"

RSA 签名

  1. 使用 sha256 生成数据摘要(256位的哈希值)
int main(int argc, char const *argv[])
{
    mbedtls_sha256_context ctx;
    unsigned char data[] = "Hello";
    unsigned char output[32] = {0};
    unsigned char sig[256] = {0};
    size_t data_len = sizeof(data) - 1; 
    mbedtls_sha256_init(&ctx);
    if (mbedtls_sha256_update(&ctx, data, data_len) != 0) {  
        printf("failed\n");
    }
    mbedtls_sha256_finish(&ctx, output);
    for (size_t i = 0; i < 256; i++)
    {
       printf("%02x", output[i]);
    }
    printf("\n");
    int sig_len;
    printf("len = %d\n", strlen(output));
    mbedtls_sha256_free(&ctx);
}
  1. 加载私钥
  2. 使用私钥对数据摘要进行签名(随机数填充)
int RSA_signature(const unsigned char* m, unsigned int m_length, unsigned char* sigret, unsigned int* siglen, const char* key)
{
    int ret;

    mbedtls_ctr_drbg_context ctr_drbg;
    mbedtls_entropy_context entropy;

    mbedtls_ctr_drbg_init(&ctr_drbg);
    mbedtls_entropy_init(&entropy);
    
    if (mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0) != 0) {
        // Handle error
        printf("random init error\n");
        ret = -1;
    } else {
        mbedtls_pk_context pk;
        mbedtls_pk_init(&pk);
        size_t keylen = strlen((const char *) key);
        // 解析公钥
        ret = mbedtls_pk_parse_key(&pk, key, keylen + 1, NULL, 0, mbedtls_ctr_drbg_random, &ctr_drbg);
        // 加载私钥
        // ret = mbedtls_pk_parse_keyfile( &pk, "cert_pri.pem", NULL, mbedtls_ctr_drbg_random, &ctr_drbg);
        if (ret != 0) {
            printf("pass private key error\n");
        } else {
            printf("pass private key success\n");

            // 执行RSA加密
            ret = mbedtls_pk_sign(&pk, MBEDTLS_MD_SHA256, m, m_length, sigret, 256, siglen,
                                    mbedtls_ctr_drbg_random, &ctr_drbg);
            if (ret != 0) {
                char error_buf[100];
                mbedtls_strerror(ret, error_buf, sizeof(error_buf));
                printf("rsa private encrypt error:%s\n", error_buf);
            }
        }
        mbedtls_pk_free(&pk);
    }
    mbedtls_ctr_drbg_free(&ctr_drbg);
    mbedtls_entropy_free(&entropy);
    return ret;
}

RSA 验签

  1. 加载公钥
  2. 验证签名
int RSA_signature_verify(const unsigned char* m, int m_length, const char* key, unsigned char* sigret, unsigned int siglen)
{
    int ret;
    mbedtls_ctr_drbg_context ctr_drbg;
    mbedtls_entropy_context entropy;

    mbedtls_ctr_drbg_init(&ctr_drbg);
    mbedtls_entropy_init(&entropy);
    mbedtls_pk_context pk;
    mbedtls_pk_init(&pk);
    ret = mbedtls_pk_parse_public_key(&pk, key, strlen(key) + 1);
    if (ret != 0) {
        printf("pass public key error\n");
        ret = -1;
    } else {
        printf("pass public key success\n");
        ret = mbedtls_pk_verify(&pk, MBEDTLS_MD_SHA256, m, m_length, sigret, (long unsigned int)siglen);
        if (ret != 0) {
            char error_buf[100];
            mbedtls_strerror(ret, error_buf, sizeof(error_buf));
            printf("rsa public encrypt error:%s\n", error_buf);
            printf("ret = %d\n", ret);
        }
    }
    mbedtls_ctr_drbg_free(&ctr_drbg);
    mbedtls_pk_free(&pk);
    mbedtls_entropy_free(&entropy);
    return ret;
}

加密数据

  1. 加载公钥
  2. 加密数据(随机数填充)
int rsa_public_encrypt(const unsigned char *public_key_pem, const unsigned char *plaintext,
                       size_t plaintext_len, unsigned char *ciphertext, size_t *ciphertext_len)
{

    int ret;

    mbedtls_ctr_drbg_context ctr_drbg;
    mbedtls_entropy_context entropy;

    mbedtls_ctr_drbg_init(&ctr_drbg);
    mbedtls_entropy_init(&entropy);

    if (mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0) != 0)
    {
        // Handle error
        printf("random init error\n");
        ret = -1;
    }
    else
    {
        mbedtls_pk_context pk;
        mbedtls_pk_init(&pk);
        size_t keylen = strlen((const char *)public_key_pem);
        // 解析公钥
        ret = mbedtls_pk_parse_public_key(&pk, public_key_pem, keylen + 1);
        if (ret != 0)
        {
            printf("pass public key error\n");
        }
        else
        {
            printf("pass public key success\n");

            // 执行RSA加密
            ret = mbedtls_pk_encrypt(&pk, plaintext, plaintext_len, ciphertext, ciphertext_len,
                                     1024, mbedtls_ctr_drbg_random, &ctr_drbg);
            if (ret != 0)
            {
                char error_buf[100];
                mbedtls_strerror(ret, error_buf, sizeof(error_buf));
                printf("rsa public encrypt error:%s\n", error_buf);
            }
        }
        mbedtls_pk_free(&pk);
    }
    mbedtls_ctr_drbg_free(&ctr_drbg);
    mbedtls_entropy_free(&entropy);
    return ret;
}

解密数据

  1. 加载私钥
  2. 解密数据
int rsa_private_decrypt(const unsigned char *private_key_pem, const unsigned char *ciphertext,
                        size_t ciphertext_len, unsigned char *plaintext, size_t *plaintext_len)
{
    int ret;

    mbedtls_ctr_drbg_context ctr_drbg;
    mbedtls_entropy_context entropy;

    mbedtls_ctr_drbg_init(&ctr_drbg);
    mbedtls_entropy_init(&entropy);

    if (mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0) != 0)
    {
        // Handle error
        printf("random init error\n");
        ret = -1;
    }
    else
    {
        mbedtls_pk_context pk;
        mbedtls_pk_init(&pk);
        size_t keylen = strlen((char *)private_key_pem);
        // 解析私钥
        ret = mbedtls_pk_parse_key(&pk, private_key_pem, keylen + 1, NULL, 0,
                                   mbedtls_ctr_drbg_random, &ctr_drbg);
        char error_buf[100];
        if (ret != 0)
        {
            printf("pass private key error\n");
            mbedtls_strerror(ret, error_buf, sizeof(error_buf));
            printf("rsa public decrypt error:%s\n", error_buf);
        }
        else
        {
            printf("pass private key success\n");
            // 执行RSA解密
            ret = mbedtls_pk_decrypt(&pk, ciphertext, ciphertext_len, plaintext, plaintext_len,
                                     512, mbedtls_ctr_drbg_random, &ctr_drbg);
            if (ret != 0)
            {
                char error_buf[100];
                mbedtls_strerror(ret, error_buf, sizeof(error_buf));
                printf("rsa public decrypt error:%s\n", error_buf);
            }
            else
            {
            }
        }
        mbedtls_pk_free(&pk);
    }
    mbedtls_ctr_drbg_free(&ctr_drbg);
    mbedtls_entropy_free(&entropy);
    return ret;
}
  • 14
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以为您提供一些关于如何集成mbedtls到FreeRTOS系统并使用mbedtls_rsa_pkcs1_verify函数接口实现RSA验签的指导。 1. 下载mbedtls库文件并解压缩。 2. 将mbedtls库文件添加到您的FreeRTOS项目中。您可以将库文件添加到您的项目中,并在Makefile或其他构建脚本中添加相应的编译选项。 3. 在您的代码中包含mbedtls库的头文件,并在需要使用RSA接口的地方调用相应的函数。例如,在使用mbedtls_rsa_pkcs1_verify函数接口实现RSA验签功能时,可以按照以下方式调用它: ``` #include "mbedtls/rsa.h" void my_rsa_verify(void) { mbedtls_rsa_context rsa; mbedtls_md_type_t md_type; const unsigned char *hash; size_t hash_len; const unsigned char *sig; size_t sig_len; mbedtls_rsa_init(&rsa, MBEDTLS_RSA_PKCS_V15, 0); // 从密钥文件中加载公钥 mbedtls_rsa_import(&rsa, n, n_len, NULL, 0, NULL, 0, e, e_len); // 获取哈希类型 md_type = mbedtls_md_get_type(hash_type); // 计算哈希值 mbedtls_md(md_type, hash, hash_len, hash_value); // 使用公钥验证签名 mbedtls_rsa_pkcs1_verify(&rsa, NULL, NULL, MBEDTLS_RSA_PUBLIC, md_type, hash_len, hash, sig); mbedtls_rsa_free(&rsa); } ``` 在上面的代码中,您需要提供以下参数:n,n_len,e,e_len是从密钥文件中加载的公钥的模数和指数;hash_type是哈希算法的类型;hash_value是要验证的数据的哈希值;sig是要验证的签名。 4. 确保在使用mbedtls RSA接口时,在FreeRTOS系统的上下文中调用它们。这意味着您需要在FreeRTOS任务中调用它们,或者使用FreeRTOS提供的其他机制(例如信号量或队列)来确保正确的上下文。 这是一个大致的指导,希望能为您提供帮助。如果您需要更详细的说明,请随时告诉我。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值