OpenSSL 3.3.1 RSA解密未自动移除填充问题排查
RSA解密后数据残留空字节,OpenSSL未自动移除填充?
编写单元测试验证RSA加解密功能时,发现解密后的数据与原始数据对比失败——解密结果末尾带有大量空字节。按预期OpenSSL应该自动移除填充,但实际并未生效。
加解密函数实现
RSA解密函数
int secure_crypto::rsa_decrypt(const std::vector<unsigned char> &data, EVP_PKEY *privateKey, std::vector<unsigned char> &decrypted) { try { //create the context for verifying using unique_ptr EVP_PKEY_CTX_free_ptr ctx(EVP_PKEY_CTX_new(privateKey, nullptr), ::EVP_PKEY_CTX_free); if (ctx == nullptr) { return -1; } //init the context for encryption if (EVP_PKEY_decrypt_init(ctx.get()) <= 0) { return -2; } //set the padding if (EVP_PKEY_CTX_set_rsa_padding(ctx.get(), RSA_PKCS1_OAEP_PADDING) <= 0) { return -3; } //set the digest if (EVP_PKEY_CTX_set_rsa_oaep_md(ctx.get(), EVP_sha256()) <= 0) { return -4; } //get the size of the encrypted data size_t decryptedLen; if (EVP_PKEY_decrypt(ctx.get(), nullptr, &decryptedLen, data.data(), data.size()) <= 0) { return -5; } //resize the encrypted vector decrypted.resize(decryptedLen); //decrypt the data if (EVP_PKEY_decrypt(ctx.get(), decrypted.data(), &decryptedLen, data.data(), data.size()) <= 0) { return -6; } return 0; } catch (const std::exception &e) { #if LOG_CRYPTO_ERRORS dbg_println("[crypto] Error while rsa decrypting: {}", e.what()); #endif return -1; } }
RSA加密函数
int secure_crypto::rsa_encrypt(const std::vector<unsigned char> &data, EVP_PKEY *pubKey, std::vector<unsigned char> &encrypted) { try { EVP_PKEY_CTX_free_ptr ctx(EVP_PKEY_CTX_new(pubKey, nullptr), ::EVP_PKEY_CTX_free); if (ctx == nullptr) { return -1; } //init the context for encryption if (EVP_PKEY_encrypt_init(ctx.get()) <= 0) { return -2; } //set the padding if (EVP_PKEY_CTX_set_rsa_padding(ctx.get(), RSA_PKCS1_OAEP_PADDING) <= 0) { return -3; } //set the digeste if (EVP_PKEY_CTX_set_rsa_oaep_md(ctx.get(), EVP_sha256()) <= 0) { return -4; } //check if data does not exceed the key size if (data.empty() || data.size() > EVP_PKEY_get_size(pubKey)) { return -7; } //get the size of the encrypted data size_t encryptedLen; if (EVP_PKEY_encrypt(ctx.get(), nullptr, &encryptedLen, data.data(), data.size()) <= 0) { return -5; } //resize the encrypted vector encrypted.resize(encryptedLen); //encrypt the data if (EVP_PKEY_encrypt(ctx.get(), encrypted.data(), &encryptedLen, data.data(), data.size()) <= 0) { return -6; } return 0; } catch (const std::exception &e) { #if LOG_CRYPTO_ERRORS dbg_println("[crypto] Error while rsa encrypting: {}", e.what()); #endif return -1; } }
单元测试代码
TEST(CryptoTests, TestRsaEncryptDecrypt) { secure_string publicKey = "-----BEGIN PUBLIC KEY----- " "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyZ+pUSCfGR5GNhpMgtPO " "3TKW8NPiSvnsG3bLgVUwMCNbN1mfPamB3kGfQPtlFOqUaEv1bjsrcBAXROhjFCMS " "ScxlW7rN996eBX8nVC3oMz3KXOnviTItjKOpN0CymL/GmNQwKz5Xmt2h7+0xgmPJ " "uBSxo3fPwG1jbevqAIieJU/ELCHuAaRY54Oga215tuPZV8O0zsMR9ZXTW7TEpntR " "CxsdICDxCIDd78Up2MRXnV2H6ugfdACjx/KvyhXeQO52l9lq0AkRVl2O5VC3s1hp " "x+oRCUv23n9XZSdCL6oZjnt2PK2eT2sWW6pTMB5kmAGWvVpeMRicc/k7Q2mgaqpE " "LwIDAQAB " "-----END PUBLIC KEY-----"; secure_string privateKey = "-----BEGIN PRIVATE KEY----- " "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDJn6lRIJ8ZHkY2 " "GkyC087dMpbw0+JK+ewbdsuBVTAwI1s3WZ89qYHeQZ9A+2UU6pRoS/VuOytwEBdE " "6GMUIxJJzGVbus333p4FfydULegzPcpc6e+JMi2Mo6k3QLKYv8aY1DArPlea3aHv " "7TGCY8m4FLGjd8/AbWNt6+oAiJ4lT8QsIe4BpFjng6BrbXm249lXw7TOwxH1ldNb " "tMSme1ELGx0gIPEIgN3vxSnYxFedXYfq6B90AKPH8q/KFd5A7naX2WrQCRFWXY7l " "ULezWGnH6hEJS/bef1dlJ0IvqhmOe3Y8rZ5PaxZbqlMwHmSYAZa9Wl4xGJxz+TtD " "aaBqqkQvAgMBAAECggEAAOMTc2VG/69wXJ/hVyFQKQa9//JefaeUwnWHp7fPEKkg " "Pvb03IM6UlIYITEhctx0P62Pv1MkQOqGiiaMqaF/jCkmBCrNAyWiHqj1tS+xLu9w " "50LaL2Ulr5XFesJaoBM8dM4JxyA1lMbvjbGNt8+6Adr4BOZVkb7hjV+OU2wA6dyb " "bE9mqCkHTjszQIaFH0KRQxVoTHhGLBcfZjaG2rnex87ZsYWRwdm6b7WRU/kGd09E " "jilF1JTMx7YBAURQVliJ5AE1hcowkPkylu6OyYKc8Z7b1PepN4g4ojunv+Kybdj+ " "HKhiQCTBksB35kSTvUGkJCgD2sbXEnt7FkPHQp7HIQKBgQD7IPd4aRNhJdQsU3PW " "d3Z3EYRBFa/Lh590tVr6aJvRrbpHdeHWLsqvYf3ZcDgsBP+ed15FrcSoytS264Iv " "2coEPwHgAsdh114nAoA7V44HQLreEVPFq80006gpY+O9o0Ylh9UUVr5BoU5iakVP " "ENafiidLG70Ayy7uWZECNh6G5wKBgQDNiN3a8WT1m4zE3K1k2gWjllTqWZ3D8k3y " "WJD3XaeG0cTJq92donYFM49dgpX5notel0t2ycCdQDrpRYrTLLpYsky54iRXu/UH " "hvHnyfC4b5g893SCgUk3NiXiSRZdA4I2+MjvI+QncYlQUbaBJP8mOu5mkQDIJtHD " "nRdYnfxXeQKBgAGDelpcb8R3IOc/fYQ+ZhVjoqNtyQh2Ac0HRswZk07ZODU0Da9n " "ysrx0UDdP0lsoknHOGc9G+FUj6Gmm7tEGcaaxp0eByucy7F6f2FcLrv2dOnfutyH " "I4589BeDxZyf/k09m1grCayFl15ae551YIXHpGL8gNAfaWIAYjJcNyTjAoGATWtW " "lhgDfXhgJ+8v6SMuqJYB2lxzTtHAhp7RzDuc1O3DAGwaiDwf1Im9YO3FbEdKHBFF " "PbN1OEZvalrllfHtJ2fR+tqx8dI8098C09p/MBno8F4NpvLoD0H4NypsoBCoReik " "V1/fmvPrUzPUWQUEjvP3xO6tqrbkoJhVqO2plZECgYBaxcjCbFVWdoCtYtCa0LWR " "dXLBjDojE3pkaS6zFfJ2VJ1zZKRQSVuJ/kOH5wCC0ihQfjJQLqJENytL74Jyc0Zm " "Mli7dgaehAI2wkSvQIrtFGI/OwDMAVEDPnu/Cto3RiBRccmYYPEMvom6yM7Ssgsr " "MUu2JiK8+YNdsj4rthOyMQ== " "-----END PRIVATE KEY-----"; secure_string data = "test"; secure_string encrypted; secure_string decrypted; EVP_PKEY *key = nullptr; ASSERT_EQ(secure_crypto::read_public_key(publicKey, &key), 0); ASSERT_TRUE(key); EVP_PKEY *privKey = nullptr; ASSERT_EQ(secure_crypto::read_private_key(privateKey, &privKey), 0); ASSERT_TRUE(privKey); secure_string encryptedData; ASSERT_EQ(secure_crypto::rsa_encrypt(data, key, encryptedData), 0); ASSERT_FALSE(encryptedData.empty()); ASSERT_EQ(encryptedData.size(), 256); secure_string decryptedData; ASSERT_EQ(secure_crypto::rsa_decrypt(encryptedData, privKey, decryptedData), 0); ASSERT_EQ(decryptedData, data); }
测试失败结果
Expected equality of these values: decryptedData Which is: { 't' (116, 0x74), 'e' (101, 0x65), 's' (115, 0x73), 't' (116, 0x74), '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', ... } data Which is: { 't' (116, 0x74), 'e' (101, 0x65), 's' (115, 0x73), 't' (116, 0x74) }
请问这可能是什么问题?我尝试查找解决方案但一无所获,虽然可以手动移除填充,但了解到OpenSSL应该自动完成该操作。
内容的提问来源于stack exchange,提问作者Kaspek
相关产品推荐
相关产品推荐

