You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 22:42:02