使用Crypto ++加密并使用Python.CRYPTO解密

时间:2017-01-17 15:24:31

标签: python c++ encryption pycrypto crypto++

我正在开发一个使用Crypto ++来使用RSA加密某些数据的项目。

这是我的Crypto ++代码:

string plain = "Text123", encoded, cipher;
string pkey = "...";

StringSource ss1(pkey, true);
RSA::PublicKey publicKey;
PEM_Load(ss, publicKey);
RSAES_OAEP_SHA_Encryptor e(publicKey);

StringSource ss2(plain, true,
    new PK_EncryptorFilter(prng, e,
        new StringSink(cipher)
    ) 
); 

StringSource ss3(cipher, true,
    new Base64Encoder(
        new StringSink(encoded)
    )
);
cout << encoded;

我试图用Python解密加密的邮件。这是我的Python代码:

from Crypto.PublicKey import RSA
from base64 import b64decode  

cipher_text = "[THE OUTPUT OF C++]"
rsakey = RSA.importKey(open("private.txt", "r").read())
raw_cipher_data = b64decode(cipher_text)
decrypted = rsakey.decrypt(raw_cipher_data)

但是我得到了不可读的角色。

我为什么会遇到不可读的角色?任何人都能帮助我吗?

提前致谢。

1 个答案:

答案 0 :(得分:0)

这里是一个完整的工作示例,用于在C ++中加密纯文本并在Python中对其进行解密:

先决条件

  • 您已生成RSA密钥对(reference)。

  • 您使用的是最新版本的crypto ++(我正在使用8.2.0),并且已应用了PEM补丁(reference)。

  • 您拥有pycryptodome的最新版本(我正在使用3.9.8)。 pycryptodome可以替代不再维护的pycrypto软件包(reference)。

加密

您的C ++做正确的事。为了完整起见,我用必要的标头包含和公共密钥反序列化扩展了您的代码:

#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;
}

解密

在您的Python代码中,您未指定填充方案。由于您的C ++代码使用OAEP / SHA1填充,因此您还必须在Python代码中指定此填充方案:

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)
相关问题