在 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 指针。它可能会导致您的问题。
我正在使用 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 是正确的
对于这些 不安全的示例,尽管通常只需要将明文拆分为与模数 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 指针。它可能会导致您的问题。