资讯动态

openssl 模拟签名验签(加密解密)详细分析

发布时间:2026/10/17 13:32:02 来源:尧图企业网站定制
一、准备文件与密钥创建示例文件echo hello world 1.txt生成 2048 位 RSA 私钥openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:2048从私钥导出公钥openssl rsa -pubout -in private_key.pem -out public_key.pem保护私钥权限chmod 600 private_key.pem二、模拟签名与验签生成签名发送方操作openssl dgst -sha256 -sign private_key.pem -out 1.sig 1.txt验证签名接收方操作openssl dgst -sha256 -verify public_key.pem -signature 1.sig 1.txt成功输出Verified OK篡改测试可选修改1.txt后再验签echo hello world! 1.txtopenssl dgst -sha256 -verify public_key.pem -signature 1.sig 1.txt输出Verification Failure三、模拟加密与解密使用公钥加密发送方操作openssl pkeyutl -encrypt -pubin -inkey public_key.pem -in 1.txt -out 1.enc使用私钥解密接收方操作openssl pkeyutl -decrypt -inkey private_key.pem -in 1.enc -out 1.dec查看解密结果cat 1.dec 输出hello world四 代码实现1基于mebelts3.4.1的实现1结构体定义mebdlts 3.4.1 安全启动中的签名头结构体定义如下#pragma pack(push, 1) typedef struct { uint32_t magic; /* 0x00: 魔数 BBEM */ uint32_t version; /* 0x04: 版本 0x00030401 */ uint32_t image_len; /* 0x08: 被保护数据总长 */ uint32_t flags; /* 0x0C: 标志位 */ uint8_t sha256_hash[32]; /* 0x10: 原始数据的哈希 */ uint8_t rsa_signature[256]; /* 0x30: RSA-2048 签名 */ uint8_t reserved[220]; /* 填充 */ } meb_sign_header_t; #pragma pack(pop)签名长度为256 字节RSA-2048 输出固定长度。哈希为SHA-256输出 32 字节。2签正文名与验签函数实现2.1 初始化上下文RSA-2048 SHA-256 PKCS#1 v2.1#include mbedtls/rsa.h #include mbedtls/sha256.h #define RSA_KEY_SIZE 2048 #define RSA_SIG_LEN (RSA_KEY_SIZE / 8) /* 256 字节 */ mbedtls_rsa_context rsa; mbedtls_rsa_init(rsa, MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA256);MBEDTLS_RSA_PKCS_V21指定使用 PKCS#1 v2.1 填充方案PSS。2.2 签名函数int meb_sign_data(const unsigned char *data, size_t data_len, const mbedtls_rsa_context *ctx, unsigned char *signature, size_t *sig_len) { unsigned char hash[32]; /* SHA-256 输出 32 字节 */ int ret; /* 1. 计算 SHA-256 摘要 */ ret mbedtls_sha256_ret(data, data_len, hash, 0); if (ret ! 0) return ret; /* 2. 使用私钥签名 */ ret mbedtls_rsa_pkcs1_sign(ctx, NULL, /* 随机数生成函数PSS 需要可传 NULL 使用内部默认 */ NULL, /* 随机数上下文 */ MBEDTLS_RSA_PRIVATE, MBEDTLS_MD_SHA256, 32, /* hashlen SHA-256 输出长度 */ hash, signature); if (ret ! 0) return ret; *sig_len RSA_SIG_LEN; /* 固定 256 字节 */ return 0; }2.3 验签函数int meb_verify_signature(const unsigned char *data, size_t data_len, const mbedtls_rsa_context *ctx, const unsigned char *signature) { unsigned char hash[32]; int ret; /* 1. 计算 SHA-256 摘要 */ ret mbedtls_sha256_ret(data, data_len, hash, 0); if (ret ! 0) return ret; /* 2. 使用公钥验签 */ ret mbedtls_rsa_pkcs1_verify(ctx, NULL, NULL, MBEDTLS_RSA_PUBLIC, MBEDTLS_MD_SHA256, 32, hash, signature); /* 返回 0 表示验签成功非 0 表示失败 */ return ret; }五异常场景举一个例子如果密钥更新了私钥没更新签名失败的例子SECSEC Calculated Hash : 9e41f2a88c33b1d1... (当前数据计算出的哈希)SECSEC RSA Verify : FAILEDSECSEC Error: Signature mismatch!SECSEC Security Alert: Halting system.可以在初始化后使用mbedtls_pk_check_pair显式验证密钥对的匹配性mbedtls_pk_check_pair函数是 Mbed TLS 提供的密钥配对检查函数用于在签名或验签操作前主动确认公钥与私钥是否匹配从而避免因密钥更新不同步导致的验签失败。#include mbedtls/pk.h #include mbedtls/ctr_drbg.h mbedtls_pk_context pub_key; mbedtls_pk_context prv_key; mbedtls_ctr_drbg_context ctr_drbg; int ret; /* 初始化并加载密钥...略 */ /* 检查公钥与私钥是否配对 */ ret mbedtls_pk_check_pair(pub_key, prv_key, mbedtls_ctr_drbg_random, ctr_drbg); if (ret ! 0) { /* 密钥不匹配记录错误并终止签名流程 */ mbedtls_printf(Key pair mismatch! ret -0x%04X\n, -ret); /* 此时应阻止使用该密钥进行签名 */ return -1; } /* 检查通过可以安全地执行签名 */ ret mbedtls_pk_sign(prv_key, MBEDTLS_MD_SHA256, hash, 32, signature, sig_len, mbedtls_ctr_drbg_random, ctr_drbg);

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑