Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RAW RSA encryption and decryption with Crypto++

Tags:

rsa

crypto++

I need to establish a secure communication between a PC and a device which supports RSA encryption and signature with SHA1. As I have already used Crypto++ in other parts of my application, I would like to utilize Crypto++ for this as well.

The device is very primitive but allows executing a program I write on it. It has raw RSA and SHAa functions built-in; However, it has very little memory to work with, 2K bytes to be precise.

I have to encrypt and sign a message from a PC. Then the device decrypts and verifies the message. The device will then reply an encrypted message and sign on it. The PC will decrypt the message and verify it afterwards. I have implemented the raw RSA encryption, signature and verification with SHA1 inside the device using the built-in functions. The messages is short enough to be done in a single round.

However, I don't know how to encrypt a message with raw RSA using Crypto++ without involving OAEP or PKCS#1. Could somebody kind enough to show me some sample code? Thanks a ton!

like image 269
crackpot Avatar asked Mar 23 '12 02:03

crackpot


People also ask

What is RSA in Crypto?

The RSA algorithm (Rivest-Shamir-Adleman) is the basis of a cryptosystem -- a suite of cryptographic algorithms that are used for specific security services or purposes -- which enables public key encryption and is widely used to secure sensitive data, particularly when it is being sent over an insecure network such as ...

What is a raw RSA key?

The Raw RSA keyring performs asymmetric encryption and decryption of data keys in local memory with an RSA public and private keys that you provide. You need to generate, store, and protect the private key, preferably in a hardware security module (HSM) or key management system.

How do I encrypt and decrypt RSA?

Encrypting and decrypting using RSA. Encryption using RSA: To encrypt a plaintext M using an RSA public key we simply represent the plaintext as a number between 0 and N-1 and then compute the ciphertext C as: C = Me mod N.

Is RSA 4096 Crackable?

Unfortunately, there is no way to crack the RSA-4096 encryption that protects the encryption key database in these ransomware attacks.


2 Answers

I don't know how to encrypt a message with raw RSA using Crypto++ without involving OAEP or PKCS#1. Could somebody kind enough to show me some sample code?

That's easy enough when you know where to look: Raw RSA from the Crypto++ wiki. The code below was taken from the page.


Encryption

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;

Decryption

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;

Here's a sample output:

$ ./cryptopp-raw-rsa.exe
message: secret
m: 736563726574h
c: 3f47c32e8e17e291h
r: 736563726574h
recovered: secret

There is one caveat: c = m ^ e mod n, so there are some limits on plaint text size and cipher text size. Essentially, m and c must be smaller than n. In this example, replacing the string secret with now is the time for all good men to come to the aid of their country would fail because it's larger than n when converted to an Integer.

You can get the maximum plain text size with the function MaxPreImage(), and the maximum cipher text size with MaxImage().


I have to encrypt and sign a message from a PC. Then the device decrypts and verifies the message. The device will then reply an encrypted message and sign on it. The PC will decrypt the message and verify it afterwards.

On the surface, this looks like it will suffer replay attacks. You might need a protocol with the protection.

like image 125
jww Avatar answered Oct 29 '22 19:10

jww


Here is a demo function I wrote when I first did RSA encryption and decryption with Crypto++. I wrote it just to understand the basics. I hope it helps:

#include <cryptopp/files.h>
#include <cryptopp/modes.h>
#include <cryptopp/osrng.h>
#include <cryptopp/rsa.h>
#include <cryptopp/sha.h>

using namespace CryptoPP;

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

    AutoSeededRandomPool rng;

    // Create a private RSA key and write it to a file using DER.
    RSAES_OAEP_SHA_Decryptor priv( rng, 4096 );
    TransparentFilter privFile( new 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;
    RSAES_OAEP_SHA_Decryptor pri( rng, 2048 );
    TransparentFilter privSink( new 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
    InvertibleRSAFunction params;
    params.GenerateRandomWithKeySize( rng, 1536 );

    std::string plain = "RSA Encryption", cipher, decrypted_data;

    RSA::PrivateKey privateKey( params );
    RSA::PublicKey publicKey( params );

    RSAES_OAEP_SHA_Encryptor e( publicKey );
    StringSource( plain, true, new PK_EncryptorFilter( rng, e, new StringSink( cipher )));

    RSAES_OAEP_SHA_Decryptor d( privateKey );
    StringSource( cipher, true, new PK_DecryptorFilter( rng, d, new StringSink( decrypted_keydata )));

    assert( plain == decrypted_data );
}
like image 3
01100110 Avatar answered Oct 29 '22 19:10

01100110