我需要在PC和支持RSA加密和SHA1签名的设备之间建立安全通信。因为我已经在我的应用程序的其他部分使用了Crypto ++,所以我也想使用Crypto ++。
该设备非常原始,但允许执行我在其上写的程序。它内置了原始RSA和SHAa功能;但是,它的内存很少,准确地说是2K字节。
我必须从PC加密并签名消息。然后,设备解密并验证消息。然后,设备将回复加密的消息并在其上签名。 PC将解密消息并在之后进行验证。我使用内置函数在设备内部使用SHA1实现了原始RSA加密,签名和验证。消息很短,需要在一轮中完成。
但是,我不知道如何使用Crypto ++使用原始RSA加密消息而不涉及OAEP或PKCS#1。有人可以向我展示一些示例代码吗?万分感谢!
答案 0 :(得分:2)
我不知道如何在没有使用Crypto ++的情况下使用原始RSA加密消息 涉及OAEP或PKCS#1。有人可以向我展示一些示例代码吗?
当你知道从哪里看时,这很容易:来自Crypto ++ wiki的Raw RSA。下面的代码来自页面。
<强>加密强>
Integer n("0xbeaadb3d839f3b5f"), e("0x11"), d("0x21a5ae37b9959db9");
RSA::PublicKey pubKey;
pubKey.Initialize(n, e);
/////////////////////////////////////////////////////////
Integer m, c;
string message = "secret";
cout << "message: " << message << endl;
// Treat the message as a big endian byte array
m = Integer((const byte *)message.data(), message.size());
cout << "m: " << hex << m << endl;
// Encrypt
c = pubKey.ApplyFunction(m);
cout << "c: " << hex << c << endl;
<强>解密强>
Integer n("0xbeaadb3d839f3b5f"), e("0x11"), d("0x21a5ae37b9959db9");
AutoSeededRandomPool prng;
RSA::PrivateKey privKey;
privKey.Initialize(n, e, d);
/////////////////////////////////////////////////////////
Integer c(0x3f47c32e8e17e291), r;
string recovered;
// Decrypt
r = privKey.CalculateInverse(prng, c);
cout << "r: " << hex << r << endl;
// Round trip the message
size_t req = r.MinEncodedSize();
recovered.resize(req);
r.Encode((byte *)recovered.data(), recovered.size());
cout << "recovered: " << recovered << endl;
以下是示例输出:
$ ./cryptopp-raw-rsa.exe
message: secret
m: 736563726574h
c: 3f47c32e8e17e291h
r: 736563726574h
recovered: secret
有一点需要注意:c = m ^ e mod n
,因此对plaint文字大小和密文大小有一些限制。基本上,m
和c
必须小于n
。在此示例中,将字符串secret
替换为now is the time for all good men to come to the aide of their country
会失败,因为它在转换为n
时会大于Integer
。
您可以使用MaxPreImage()
函数获取最大纯文本大小,使用MaxImage()
获取最大密文大小。
我必须从PC加密并签名消息。然后设备解密 并验证消息。然后,设备将回复加密的消息 并在上面签名。 PC将解密消息并在之后进行验证。
从表面上看,这似乎会遭受重播攻击。您可能需要具有保护的协议。
答案 1 :(得分:1)
这是我第一次使用Crypto ++进行RSA加密和解密时编写的演示函数。我写这篇文章只是为了理解基础知识。我希望它有所帮助:
#include <cryptopp/files.h>
#include <cryptopp/modes.h>
#include <cryptopp/osrng.h>
#include <cryptopp/rsa.h>
#include <cryptopp/sha.h>
void rsa_examples()
{
// Keys created here may be used by OpenSSL.
//
// openssl pkcs8 -in key.der -inform DER -out key.pem -nocrypt
// openssl rsa -in key.pem -check
CryptoPP::AutoSeededRandomPool rng;
// Create a private RSA key and write it to a file using DER.
CryptoPP::RSAES_OAEP_SHA_Decryptor priv( rng, 4096 );
CryptoPP::TransparentFilter privFile( new CryptoPP::FileSink("rsakey.der") );
priv.DEREncode( privFile );
privFile.MessageEnd();
// Create a private RSA key and write it to a string using DER (also write to a file to check it with OpenSSL).
std::string the_key;
CryptoPP::RSAES_OAEP_SHA_Decryptor pri( rng, 2048 );
CryptoPP::TransparentFilter privSink( new CryptoPP::StringSink(the_key) );
pri.DEREncode( privSink );
privSink.MessageEnd();
std::ofstream file ( "key.der", std::ios::out | std::ios::binary );
file.write( the_key.data(), the_key.size() );
file.close();
// Example Encryption & Decryption
CryptoPP::InvertibleRSAFunction params;
params.GenerateRandomWithKeySize( rng, 1536 );
std::string plain = "RSA Encryption", cipher, decrypted_data;
CryptoPP::RSA::PrivateKey privateKey( params );
CryptoPP::RSA::PublicKey publicKey( params );
CryptoPP::RSAES_OAEP_SHA_Encryptor e( publicKey );
CryptoPP::StringSource( plain, true, new CryptoPP::PK_EncryptorFilter( rng, e, new CryptoPP::StringSink( cipher )));
CryptoPP::RSAES_OAEP_SHA_Decryptor d( privateKey );
CryptoPP::StringSource( cipher, true, new CryptoPP::PK_DecryptorFilter( rng, d, new CryptoPP::StringSink( decrypted_keydata )));
assert( plain == decrypted_data );
}