我正在使用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;
}
答案 0 :(得分:4)
Richard Critten是正确的in his comment,通常使用混合加密(非对称密码,如带有对称密码的RSA,如AES)。
对于这些不安全的例子,尽管通常只需要将明文拆分成与模数n
相同的部分。因此,在您的情况下,只需将每8个字节/字符放在一起,并将其用于(大端)数字。由于输入似乎是ASCII,这8个字节的最高位总是设置为零,因此加密/解密时不应该有任何问题。 RSA的输入当然必须始终小于n
。
你当然可以想出一种处理字符串最后部分的聪明方法。
注意:
答案 1 :(得分:2)
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]
来获取非const指针。它可能会导致您的问题。