简体   繁体   中英

Encrypt and Decrypt a message using raw RSA algorithm in Crypto++?

I am using Crypto++ library for cryptography related works. And sub-part of task is to encrypt and decrypt a text. The message can be up to 256 character long containing alphanumeric number spaces dot and special characters.

This piece of code is working for text length is less than or equal to 8. But after that it fails to decrypt the encrypted text.

// 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 is correct in his comment that usually hybrid encryption is used (an asymmetric cipher such as RSA with a symmetric cipher such as AES).

For these kind of insecure examples though you are usually simply required to split up the plaintext into parts the same size as the modulus n . So in your case just put every 8 bytes / characters together and use it for a (big endian) number. As the input seems to be ASCII the highest bit of those 8 bytes will always be set to zero, so you should not have any problems encrypting/decrypting. The input for RSA must of course always be less than n .

You may of course have to think up a smart way of handling the last part of the string.


Notes:

  • In case it hasn't been told (yet): raw RSA without padding is not secure either. So it is not just the key size that would be a problem if this example would be implemented in the field.
  • I haven't got a clue what you're doing with regard to decryption. You should have a look at your textbook again I suppose.
 Integer m((const byte *)message.data(), message.size()); 

If you use message.size()+1 , then the message will include the trailing NULL . You can use it during decryption to determine where the recovered string ends. Otherwise, you are going to need to track length of the message.

You might also be interested in Raw RSA from the Crypto++ wiki. But as Maarten cautined, its tricky to get right and build into a scheme.

You might consider something using RSA encryption with OAEP or PKCS v1.5 padding. Also see RSA Encryption Schemes on the Crypto++ wiki.


I believe this is undefined behavior:

 std::string recovered; recovered.resize(r.MinEncodedSize()); r.Encode((byte *)recovered.data(), recovered.size()); 

I think you need to use &recovered[0] to get the non-const pointer. It may be causing your problem.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM