RSA算法(一)-公钥加密-RSAES-PKCS1-v1_5

发布时间:2026/7/2 21:39:12
RSA算法(一)-公钥加密-RSAES-PKCS1-v1_5 文章目录0前言1 什么是RSAES-PKCS1-v1_52 加密原理3 代码实现0前言PKCS#1中定义两套加密方案两套签名方案。由于加密方案能够加密的字节数很小通常是用于协商对称密钥而使用在日常工作中接触更多场景的是签名场景而非加密场景由于最近项目中在诊断0x 27场景使用到了Encryption schemes借此机会对代码分析并对原理进一步分析1 什么是RSAES-PKCS1-v1_5RSAES-PKCS1-v1_5是基于RSA算法的加密算法RSAES-PKCS1-v1_5 与 RSAES-OAEP的区别在于encoding过程有就是填充方式的差异下边展示了两个encoding过程这里会发现两者编码差异很大本章节对于EME-OAEP Encoding Operation仅做简单介绍详细介绍将在另外一篇文章科普EME-PKCS1-v1_5 encoding步骤简单其中PS是pseudo-randomly 随机数每次加密结果不同EME-OAEP Encoding Operation步骤复杂seed为随机数MGF为掩码函数EME-PKCS1-v1_5 encodingEM 0x00 || 0x02 || PS || 0x00 || M.EME-OAEP Encoding Operation------------------------- DB | lHash | PS |01| M | ------------------------- | ---------- | | seed | | ---------- | | | |------- MGF --- xor | | -- V | |00| xor ----- MGF -----| -- | | | | | V V V ---------------------------------------- EM |00|maskedSeed| maskedDB | ----------------------------------------RSA encryption过程是相同m OS2IP (EM). c RSAEP ((n, e), m) C I2OSP (c, k).2 加密原理参数英文名称中文名称(M)Message明文(mLen)Message Length明文长度(PS)Padding String随机填充字符串(EM)Encoded Message编码后的消息(m)Message Representative消息整数表示©Ciphertext Representative密文整数表示©Ciphertext最终密文(n)RSA ModulusRSA 模数(e)Public Exponent公钥指数(d)Private Exponent私钥指数(k)Modulus LengthRSA 模长ByteOS2IPOctet String to Integer Primitive字节串转整数I2OSPInteger to Octet String Primitive整数转字节串RSAEPRSA Encryption PrimitiveRSA 加密原语RSADPRSA Decryption PrimitiveRSA 解密原语RSAES-PKCS1-v1_5 Encryption Message M │ ▼ Generate Random PS 填充PS为随机数 │ ▼ EM 00 || 02 || PS || 00 || M │ ▼ m OS2IP(EM) │ ▼ c m^e mod n │ ▼ C I2OSP(c)3 代码实现#include mbedtls/pk.h #include mbedtls/entropy.h #include mbedtls/ctr_drbg.h #include mbedtls/error.h #include stdio.h #include string.h int rsa_public_encrypt(const char *pub_key_path, const unsigned char *input, size_t input_len, unsigned char *output, size_t *output_len) { int ret; mbedtls_pk_context pk; mbedtls_entropy_context entropy; mbedtls_ctr_drbg_context ctr_drbg; const char *pers rsa_pk_encrypt; // 初始化PK上下文 // 初始化CTR_DRBG上下文 // 初始化熵上下文 mbedtls_pk_init(pk); mbedtls_entropy_init(entropy); mbedtls_ctr_drbg_init(ctr_drbg); // RNG初始化必须 ret mbedtls_ctr_drbg_seed( ctr_drbg, mbedtls_entropy_func, entropy, (const unsigned char *)pers, strlen(pers) ); if (ret ! 0) { printf(RNG init failed\n); return ret; } // 读取公钥2.16支持这个API ret mbedtls_pk_parse_public_keyfile(pk, pub_key_path); if (ret ! 0) { char err[128]; mbedtls_strerror(ret, err, sizeof(err)); printf(PK parse failed: %s\n, err); goto exit; } // 检查是不是RSA if (!mbedtls_pk_can_do(pk, MBEDTLS_PK_RSA)) { printf(Not RSA key\n); ret -1; goto exit; } size_t olen 0; // RSA 加密PKCS#1 v1.5 ret mbedtls_pk_encrypt( pk, input, input_len, output, olen, 256, // 2048-bit RSA 256 bytes mbedtls_ctr_drbg_random, ctr_drbg ); if (ret 0) { *output_len olen; } else { char err[128]; mbedtls_strerror(ret, err, sizeof(err)); printf(Encrypt failed: %s\n, err); } exit: mbedtls_pk_free(pk); mbedtls_ctr_drbg_free(ctr_drbg); mbedtls_entropy_free(entropy); return ret; } int main() { // 加密公钥路径 const char *pub_key mbedtls_rsa_sig/key/public_key.pem; // 明文数据 unsigned char plaintext[] Hello RSA mbedTLS 2.16; // 密文数据变量 unsigned char ciphertext[256]; // 密文数据长度变量 size_t ciphertext_len 0; int ret rsa_public_encrypt( pub_key, plaintext, strlen((char *)plaintext), ciphertext, ciphertext_len ); if (ret 0) { printf(Encrypt OK!\nHEX:\n); for (size_t i 0; i ciphertext_len; i) { printf(%02X, ciphertext[i]); } printf(\n); } return ret; }