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

好久不见. 提交于 2019-12-13 15:59:24

问题


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;
}

回答1:


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.



回答2:


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.



来源:https://stackoverflow.com/questions/42046991/encrypt-and-decrypt-a-message-using-raw-rsa-algorithm-in-crypto

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!