在 Crypto++ 中使用原始 RSA 算法加密和解密消息?

Encrypt and Decrypt a message using raw RSA algorithm in Crypto++?

我正在使用 Crypto++ 库进行密码学相关工作。任务的子部分是加密和解密文本。消息最长可达 256 个字符,包含字母数字空格点和特殊字符。

这段代码适用于文本长度小于或等于8。但之后它无法解密加密文本。

// g++ -std=c++1y crypto.cpp -I /home/shravan40/cryptopp/build -lcryptopp

#include <iostream>

#include <cryptopp/rsa.h>
#include <cryptopp/integer.h>
#include <cryptopp/osrng.h>

int main(){
    // Keys
    CryptoPP::Integer n("0xbeaadb3d839f3b5f"), e("0x11"), d("0x21a5ae37b9959db9");

    CryptoPP::RSA::PrivateKey privKey;
    privKey.Initialize(n, e, d);

    CryptoPP::RSA::PublicKey pubKey;
    pubKey.Initialize(n, e);

    // Encryption
    std::string message = "Shravan Kumar";
    CryptoPP::Integer m((const byte *)message.data(), message.size());
    std::cout << "m: " << m << std::endl;
    // m: 126879297332596.

    CryptoPP::Integer c = pubKey.ApplyFunction(m);
    std::cout << "c: " << std::hex << c << std::endl;
    // c: 3f47c32e8e17e291h

    // Decryption
    CryptoPP::AutoSeededRandomPool prng;
    CryptoPP::Integer r = privKey.CalculateInverse(prng, c);
    std::cout << "r: " << std::hex << r << std::endl;

    // r: 736563726574h
    std::string recovered;
    recovered.resize(r.MinEncodedSize());

    r.Encode((byte *)recovered.data(), recovered.size());
    std::cout << "recovered: " << recovered << std::endl;

    // recovered: Expected : (Shravan Kumar), Received -> y5��dqm0
    return 0;
}

Richard Critten 是正确的 通常使用混合加密(非对称密码如 RSA 和对称密码如 AES)。

对于这些 不安全的示例,尽管通常只需要将明文拆分为与模数 n 大小相同的部分。因此,在您的情况下,只需将每 8 个字节/字符放在一起并将其用于(大端)数字。由于输入似乎是 ASCII,这 8 个字节的最高位将始终设置为零,因此您应该没有任何问题 encrypting/decrypting。 RSA 的输入当然必须始终小于 n.

当然,您可能必须想出一种巧妙的方法来处理字符串的最后部分。


备注:

  • 以防万一(还)没有被告知:没有填充的原始 RSA 也不安全。因此,如果在现场实施此示例,不仅仅是密钥大小会成为问题。
  • 关于解密,我不知道你在做什么。我想你应该再看看你的课本。
Integer m((const byte *)message.data(), message.size());

如果您使用 message.size()+1,则消息将包含结尾的 NULL。您可以在解密期间使用它来确定恢复的字符串结束的位置。否则,您将需要跟踪消息的长度。

您可能还对来自 Crypto++ wiki 的 Raw RSA 感兴趣。但正如 Maarten 所警告的那样,要正确并建立一个计划是很棘手的。

您可能会考虑使用带有 OAEP 或 PKCS v1.5 填充的 RSA 加密。另请参阅 Crypto++ wiki 上的 RSA Encryption Schemes


我认为这是未定义的行为:

std::string recovered;
recovered.resize(r.MinEncodedSize());
r.Encode((byte *)recovered.data(), recovered.size());

我认为您需要使用 &recovered[0] 来获取 non-const 指针。它可能会导致您的问题。