Here is a full working example for encrypting the plaintext in C++ and decrypting it in Python:
Prerequisites
You have generated an RSA key pair (reference).
You have a recent version of crypto++ (I am using 8.2.0) and you have applied the PEM patch (reference).
You have a recent version of pycryptodome (I am using 3.9.8). pycryptodome is a drop-in replacement for the no-longer maintained pycrypto package (reference).
Encryption
Your C++ does the right thing. For the sake of completeness, I extended your code with the necessary header includes and the deserialization of the public key:
#include <cryptopp/base64.h>
#include <cryptopp/files.h>
#include <cryptopp/filters.h>
#include <cryptopp/osrng.h>
#include <cryptopp/pem.h>
#include <cryptopp/rng.h>
#include <cryptopp/rsa.h>
#include <iostream>
int main(int argc, char **argv) {
CryptoPP::AutoSeededRandomPool prng{};
std::string plain{"Text123"};
/**
* Read public key in PEM format.
*/
CryptoPP::FileSource fs{"public.pem", /*pumpAll=*/true};
CryptoPP::RSA::PublicKey publicKey{};
PEM_Load(fs, publicKey);
std::string encrypted{};
/**
* Pump plain text through RSA encryption scheme with OAEP/SHA1 padding.
*
* In general, manual memory allocations should be avoided. However,
* the CryptoPP API expects us to allocate memory for each transformer and
* then pass the pointer to the next transformer, which then takes ownership
* of the pointer and will free it. This design obviously predates
* modern C++ smart pointers, which should be preferred when possible.
*/
CryptoPP::RSAES_OAEP_SHA_Encryptor cipher{publicKey};
auto *encoder{
new CryptoPP::Base64Encoder{new CryptoPP::StringSink{encrypted}}};
auto *encryptor{new CryptoPP::PK_EncryptorFilter{prng, cipher, encoder}};
CryptoPP::StringSource ss{plain, /*pumpAll=*/true, encryptor};
std::cout << encrypted;
return 0;
}
Decryption
In your Python code you are not specifying the padding scheme. Since your C++ code uses OAEP/SHA1 padding, you also have to specify this padding scheme in your Python code:
from base64 import b64decode
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
from Crypto.Hash import SHA1
rsa_key = None
encrypted = None
with open("key.pem", "r") as f:
rsa_key = RSA.importKey(f.read())
with open("encrypted", "r") as f:
encrypted = b64decode(f.read())
cipher = PKCS1_OAEP.new(rsa_key, hashAlgo=SHA1)
decrypted = cipher.decrypt(encrypted)
print(decrypted)