ESP32上使用mbedtls进行RSA2048解密失败求助
RSA2048解密函数错误分析(ESP32 + mbedtls)
你的解密代码存在两个核心错误,直接导致了0x4080(输入参数非法)的错误码:
1. 直接传入Base64字符串作为解密输入
mbedtls_pk_decrypt要求的是加密后的原始二进制数据,但你传入的是Base64编码后的文本字符串。Base64是为了方便文本传输设计的编码格式,无法被RSA解密函数直接识别,必须先将其解码为二进制数组。
2. 错误计算解密数据长度
你用(strlen(text)*4)-1来计算解密数据长度,这是完全错误的逻辑。Base64编码后的长度与解码后的二进制长度没有固定换算关系,必须通过mbedtls_base64_decode函数获取实际解码后的二进制长度。
修正后的decrypt_test函数代码
void decrypt_test() { const unsigned char *private_key = (const unsigned char *)"-----BEGIN RSA PRIVATE KEY-----\n" "MIIEogIBAAKCAQEAmwukduTT4dMD+EXuho4LzEg9pH7Bk4y6TPw9pQqiw4b5Qx3+\n" "KM+SFi2I4AncfkOcjtuMqtSPdNSgFb1DErQD+I+yOS7ztuAVy6hO/oRpVKAJNVl3\n" "85pC/Ah8aiZts6cY8kjs47Mw4ufFNwIH8hOy6f1+e8chBgeKxOVJBNiWr2nsPhvv\n" "AERTunw/CTvWsBLakyGs+OJwOcYsr0m5iOJxXfBUEYOQ68XDIUTTLKdYsUOFSESw\n" "tIsPgqytj+SRcA/STH8eQJigNQNj8Zexpi+3ykDWAxbmHQ8UWma1vV//oM6xy3DI\n" "/SXxvPusjNbKxDg+q5/e3hWoaBVq3ti9/ZTekQIDAQABAoIBADXzji5FICnDuOzq\n" "wL6XrSlPtguIhCmo3acuWvEUS2EIlbIyPJ/M4wPOooN7Svuw4Uigw0kqoCTCXFZU\n" "PoPCmmMi9ZyKZwoq3cq5bYuJXfGxoqKq2F+vPUHgXhK9/ox2R+r/T1dIomlCx1CF\n" "52foTOi5agr+VtJ3S2WKd6c1CvJMuRRoIX9vI49L+NdA9FUcA4Ge2rJZPu7zd/Xj\n" "VvqtIH63Y/4z+S5YqnBgYjk7xWf3f9ybrkdi9fiRNt9wq4LOet+OSiQXWyuX+ppL\n" "im6Sl3O8XkaDWAFo8dUWkZf+6RpABxFnUy45CWZGs7W8MpVwykXdpxcn9iJ7jIaR\n" "9dcmUgECgYEA3aAWxuiX081mFIdmQEpKkp1JFbZOoZpIzBXNx/M05FGkz8QPL7G3\n" "9h8A8UCbTFG+cAM1vjMUPzWXbsytE8VC4qjGy+1RBDltBt5/XX4VECVDIwjTdmc0\n" "RPfJ2vKkAFYPHjyQijQCZxAPM0E/IFGKnTP4Dt+rITxkYvoouFiR2eECgYEAsxfq\n" "qk2d8K62DQPURHvNmFnct+QAlIF9i/XHGcLNvnzEASiIsZ75TiXUc0xIxY2/ewo4\n" "CMbNUG98xiW0Q5pdyKFQ3qnhNNTKPCK1T4qqKarDU2pSXFC2afkCSBbfO7qWblRD\n" "PMJJ7SG8fAeIWbqKVzPgSfwRw4xY+iEe7SvoerECgYAEIQhrmkfB3XDKbx9bkUbE\n" "ZoPHEMd0QVCb5MgZspFIs7CzYj66L8ByqG83D3IVQOygX57vtTnqV5BDszKCTMmL\n" "OYPCpuA8iOlcGGcdEc1IqLkQfQibix6xLkCngJ/HldLgSFaVDJUC4Iy38r4/VuWT\n" "OjWj6Uzh6KMiKPD7RkMpYQKBgH2BSjM0l3U+ilfOkie39tlISDQaNQndQQUfJPr5\n" "mENgnd8N79VBygYo3pw6HllLP5/TBneoEePHbVJSw+QIPqbF3a1csXTblinUTOlE\n" "DIGMqLtBLByDd4IGPcIVPTVXSephZIkkwrfKR5NHmBcBcccwlIJkgnJeXVBUe57L\n" "gWzRAoGAAmLnPNkIT5Nruqy7EdEeb90W0VA/7/CaESvZKUkAHUy4bIqwFSGGJz1Q\n" "oKUx8cuK4tz79mHsjzlJoCSLUvI5Fpfz+CS9uvA15QBIHU+5G37Ga5WsuBTww+lx\n" "XC6IQ356/xfs4CmAVD1xjhEuBjANSs8lgHMAQPGngU5EVaE1hPw=\n" "-----END RSA PRIVATE KEY-----"; // RNG初始化部分保持不变 int ret = 0; mbedtls_entropy_context entropy; mbedtls_entropy_init(&entropy); mbedtls_ctr_drbg_context ctr_drbg; const char *personalization = "mgkegneljgnjlwgnjefdcmeg12313123dsggsd"; mbedtls_ctr_drbg_init(&ctr_drbg); ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, (const unsigned char *)personalization, strlen(personalization)); if (ret != 0) { // 错误处理 } // 加载私钥部分保持不变 mbedtls_pk_context pk; mbedtls_pk_init(&pk); if ((ret = mbedtls_pk_parse_key(&pk, private_key, strlen((const char *)private_key) + 1, NULL, 0)) != 0) { printf(" failed\n ! mbedtls_pk_parse_key returned -0x%04x\n", -ret); goto exit; // 错误时跳转到资源释放 } unsigned char result[MBEDTLS_MPI_MAX_SIZE]; size_t olen = 0; // 待解密的Base64字符串 const char *b64_text = "fnianPxs/09bx75ufVLWPeFF9kbGEIL3+TQqW2+ZoeMpdvVnkifFToAii92ODVBPOL0RzQPfxlJcN/nVY3K5fWNSGHM8TTwTgCqvUc0ia5L5YHI1YSgDKzx2QPZlu7tEd06sjW7txRacnhilRfjFPp0CYeLwxYVBlPmKIE7oqQHrc8sal3X9NSqgwO7+03TBeH3beNanMCqQBRk9t+Z80XApEBMcZQHZ0lb+Z0C6DOuY0elH/fOp1SGlXuzf+tgcv7+TzL5uVVFCBNyMonTwMEp+zbLjX2Ck1IHhp8JXi3ovVi8HNcKCOQx/fxX1qTSt2NulHTwP2urCQSZbGjnYuw=="; // 第一步:Base64解码成二进制数据 unsigned char to_decrypt[MBEDTLS_MPI_MAX_SIZE]; size_t decrypt_len = 0; ret = mbedtls_base64_decode(to_decrypt, sizeof(to_decrypt), &decrypt_len, (const unsigned char*)b64_text, strlen(b64_text)); if(ret != 0) { printf(" failed\n ! mbedtls_base64_decode returned -0x%04x\n", -ret); goto exit; } // 第二步:调用解密函数,传入解码后的二进制数据和实际长度 printf("\n . Generating the decrypted value"); fflush(stdout); if ((ret = mbedtls_pk_decrypt(&pk, to_decrypt, decrypt_len, result, &olen, sizeof(result), mbedtls_ctr_drbg_random, &ctr_drbg)) != 0) { printf(" failed\n ! mbedtls_pk_decrypt returned -0x%04x\n", -ret); } else { // 打印解密结果(假设是字符串) printf("\nDecrypted result: %.*s\n", (int)olen, result); } exit: // 释放资源 mbedtls_pk_free(&pk); mbedtls_entropy_free(&entropy); mbedtls_ctr_drbg_free(&ctr_drbg); }
额外注意事项
- 加密和解密的填充方式必须一致:你的加密代码使用带随机数的
mbedtls_pk_encrypt,默认采用RSAES-OAEP填充,解密时mbedtls会自动识别该填充格式,无需额外配置。 - 资源释放:添加
goto exit逻辑,确保错误发生时也能正确释放mbedtls上下文,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Resent
相关产品推荐
相关产品推荐

