使用Crypto ++进行RAW RSA加密和解密

时间:2012-03-23 02:50:44

标签: rsa crypto++

我需要在PC和支持RSA加密和SHA1签名的设备之间建立安全通信。因为我已经在我的应用程序的其他部分使用了Crypto ++,所以我也想使用Crypto ++。

该设备非常原始,但允许执行我在其上写的程序。它内置了原始RSA和SHAa功能;但是,它的内存很少,准确地说是2K字节。

我必须从PC加密并签名消息。然后,设备解密并验证消息。然后,设备将回复加密的消息并在其上签名。 PC将解密消息并在之后进行验证。我使用内置函数在设备内部使用SHA1实现了原始RSA加密,签名和验证。消息很短,需要在一轮中完成。

但是,我不知道如何使用Crypto ++使用原始RSA加密消息而不涉及OAEP或PKCS#1。有人可以向我展示一些示例代码吗?万分感谢!

2 个答案:

答案 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文字大小和密文大小有一些限制。基本上,mc必须小于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 );
}