RSA 加密然后解密失败,并显示“oaep 解码错误”

qdi*_*dii 8 c++ encryption openssl rsa

我正在尝试调试一个简单的 openssl 程序,但无法完全理解 openssl 的“oaep 解码错误”含义。我已将我的程序简化为这个,测试,一个:

\n\n
#include <iostream>\n#include <openssl/evp.h>\n#include <openssl/rsa.h>\n#include <openssl/pem.h>\n#include <openssl/err.h>\n#include <assert.h>\n#include <memory>\n#include <list>\n#include <algorithm>\n#include <string.h>\n\nstatic const std::string private_key =\nR"(-----BEGIN RSA PRIVATE KEY-----\nMIIEogIBAAKCAQEAriDoH3gBbJo+SojeL5j+4yQumXgnjhrt5+FChBxOfvTcyczz\np5qlUNqLzQQcQ/a+XR5qUhaA4l97DgNseFNyoYHIxrB5t+BQw27Q+UuUYYaIwJqZ\n6r2PVCnQF9WPqqWdzBN6+13IlreH2XX4qy47kuLI3lcPlP5qhYaDogpZCl7lN7Oe\nQj2FAPZ1nkV+PL4RYfWZbBymUz0C105ytT7PWgLAZVvag8kHiNXRYv4Ksc9SJ3AE\nZriZ1tzpJ6/ZkI3vfJZqCeclELQ8zGxb8CbfSd4mHoHCVY7t1h+BNM4zUxSjN8d7\nbctYJwnfBtztRFN2uTotDJs6njsoxfmh4/SzAQIDAQABAoIBAAGTWKZYPqMN7jxc\naq5BkyTZAfbviGQXyElN1308iFVLv+evjBDbLF3D7HnpbJwM0oIjMVEW1Qm3VXS2\nAThBgQsHEpsBo8hPJkvuZ8OptGkBf6FGhNgD6RUY38Inc4pWv0vGbVly6sq6VGda\nUuqxm2Zj2O9yGDj/6FTW97/ymgWm/FfKczg/zGtjdog67W8LvvtmAj5ynSuimOP8\nmOINPjewIbcl7rKvxcMNrOXKsRWwVxTNXdMNMsXd1Figw022KTqdiazQ/DPIXU6M\nf8H+U/gS5QZRIAF8i0r3cvq6ai26dX0OFtsoizqG4qlRNwtQ+wyRsilZKiKnFuMY\nbt1pRBUCgYEA1TlAT/Ui4TBdgGmm0Rlj7JKJENnpDKIFE8bP6Vy8SwBmp5MiRofE\nTMne4BBKLcFcslCJrFvjl7+v4B9a2de7hJYqtevrXjM91vwFhc6z0m27vv6MKStQ\n3uKX8+0RGHQ3j53kAvLxFSuAqYQ+gf9IAuyG0gpMABRvj0/8HY3T7tMCgYEA0Q/O\n0og9UbXh8y3yI94ztczWdIQERyEhQiGNRUnHCqO2QbZQ9Nm190Jx/8yew03xpPVb\nfyWWfKqO8Kjg5np0w37porI0UmfLZ5QMC+GFMq0jOUXidsvkyoWOe4D8LII0L98k\nsjihHBlGNrfFjEgOUQaoreB+8F07m/iofRCROlsCgYAPUUGRfOa4jqTo6K4XL1/C\nSvSVxVG8mpcKyKl+9i6ApNK7DxLTRkWPzqC4L/NkPhPOq4J4Y1GCQT79NsNsCtdp\nuu/uibgq2DuFCi3LYwIAB+oI2nhvLLFukZCg8VLdEtw68PjETXeMMcfYZaun4xLl\nQuCcjijPiKhK/0/5P4sOCQKBgHsi7XXRqxRapdg/ArUfpqN5IAOG0qI2oEk8S+I4\nv1TD8pCn2u0s4mHdsBmzovt0CFVZ8udj80xAhWq4facjD20qbmBWyDyVSBgc+i9x\nSKv9kJamU+oW1A55NeAGrAFnO2fK7elPM43CUTnfairjMhOFcYrghMP8liSbBFqN\njIyrAoGAVGZQVZgicmSppbBuZYJPOuegPVYhncq3XtBZCtEGGlMtQpKgz+GRhyvT\nAr/HC7xnS5Gjfyjj6eGHsBAjTsE4t38qD4nxQXzBmAQQ1/7/iq3WNu63OV2q4GRh\nwChOO0pcJPOZfWtvKiy7hbN09e0nt5blX1yqe6LdO7mACWli/Ss=\n-----END RSA PRIVATE KEY-----)";\n\nstatic const std::string public_key = \nR"(-----BEGIN RSA PUBLIC KEY-----\nMIIBCAKCAQEAx5WRSyfFVe/JbPYnswghuMj5Nzo9YG82Z7ehyI/dbjkcdCIzTlKd\nQcMvSUZafAnM9p3xnBrgbKaNltaVNrZNyN6A2ou0PQgms7ykJ67G9Hbbs/uo0rPS\nGS4pYw0QiOvoYXjGqbOzQjXbAV7ez05XRb43nRdZUFO0LLvEp2VfaTL7WWzaan6r\nVe6p8t8JIwpWSn7njBYH2XPNJj1NccpvD+kT1kGn6kWZfmFBzR7Bw2+rW+rpt02F\n4arxXfvzDYhZdxLKb7m2KqwZTiug2HoD5AY9l3GzRIdNvXIDP87XTl4960lpg8cI\n8XuTSLFjSx0fvlXXFwTcgMLv7Q0+ISSXQwIBJQ==\n-----END RSA PUBLIC KEY-----)";\n\nstatic inline \nvoid check_errors()\n{\n    const int error = ERR_get_error();\n    if ( error != 0 )\n    {\n        std::cerr << ERR_reason_error_string( error ) << \'\\n\';\n        assert(0);\n    }\n}\n\nint main()\n{\n    ERR_load_crypto_strings();\n\n    // load rsa keys into a memory buffer\n    BIO * bio_private = BIO_new_mem_buf( (char*) private_key.data(), private_key.size()  ); check_errors();\n    BIO * bio_public  = BIO_new_mem_buf( (char*) public_key.data(),  public_key.size()  ); check_errors();\n\n    // use the memory buffer to create a RSA\xc2\xa0struct\n    RSA * rsa_private = RSA_new(); check_errors();\n    RSA * rsa_public  = RSA_new(); check_errors();\n\n    PEM_read_bio_RSAPrivateKey( bio_private, &rsa_private, nullptr, 0 ); check_errors();\n    PEM_read_bio_RSAPublicKey(  bio_public,  &rsa_public,  nullptr, 0 ); check_errors();\n\n    // encrypt this text ...\n    std::string text_to_encrypt = "hello";\n\n    // ... in this buffer\n    std::vector< unsigned char > buffer;\n    buffer.resize( RSA_size( rsa_private ) );\n\n    const int flen = RSA_public_encrypt( \n                text_to_encrypt.size(), // shorter than the key in my test\n                (const unsigned char*)text_to_encrypt.data(),\n                &buffer[0],\n                rsa_public,\n                RSA_PKCS1_OAEP_PADDING\n            ); check_errors();\n\n    // now decrypt the buffer back to the original text\n    std::vector< unsigned char > buffer_decrypt;\n    buffer_decrypt.resize( RSA_size( rsa_private ), \'\\0\' );\n\n    RSA_private_decrypt(\n                flen, \n                &buffer[0],\n                &buffer_decrypt[0],\n                rsa_private,\n                RSA_PKCS1_OAEP_PADDING\n            ); check_errors();\n\n    // and print it\n    std::cout << (char*) &buffer_decrypt[0] << \'\\n\';\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

位于触发器check_errors()之后RSA_private_decrypt,并出现提到的错误,我\xc2\xa0不知道为什么。

\n\n

编辑:通过使用 RSA_public_crypt 返回的值稍微改进了代码。实际上,这并不影响结果。

\n

jww*_*jww 7

位于 RSA_private_decrypt 之后的 check_errors() 会触发上述错误,我不知道为什么。

您的公钥与私钥不匹配。

当我在读取密钥后添加以下内容时:

FILE* ff = fopen("temp.pem", "w");
PEM_write_RSAPublicKey(ff, rsa_private);
Run Code Online (Sandbox Code Playgroud)

然后是cat公钥:

FILE* ff = fopen("temp.pem", "w");
PEM_write_RSAPublicKey(ff, rsa_private);
Run Code Online (Sandbox Code Playgroud)

答对了!它与硬编码的公钥不匹配。

如果您想超越它进行测试,只需使用它rsa_private进行加密即可。在以下期间仅使用密钥的公共部分RSA_public_encrypt

int flen = RSA_public_encrypt( 
               text_to_encrypt.size() + 1,
               text_to_encrypt.data(),
               &buffer[0],
               rsa_private,
               RSA_PKCS1_OAEP_PADDING
            );
Run Code Online (Sandbox Code Playgroud)

或者,现在您知道公钥应该是什么,只需更新它即可。