smbullet
smbullet

Reputation: 313

Why does Crypto++ think my messages are larger than they are?

I'm using the Crypto++ library for C++ to encrypt 128-bit messages with their public key and my private key from disk. However, when I call my function the program terminates with the error message:

terminate called after throwing an instance of 'CryptoPP::InvalidArgument' what(): RSA/OAEP-MGF1(SHA-1): message length of 256 exceeds the maximum of 214 for this public key

I'm not sure why it thinks my messages are 256-bit when they are clearly 128-bit. Below is my code:

std::string encryptWithBothKeys(std::string key_name1, std::string key_name2, std::string plain){
    std::string cipher1, cipher2;
    AutoSeededRandomPool rng;

    RSA::PublicKey pub_key;
    RSA::PrivateKey priv_key;
    loadPublicKey(key_name1, pub_key);
    loadPrivateKey(key_name2, priv_key);

    RSAES_OAEP_SHA_Encryptor e_pub(pub_key);
    RSAES_OAEP_SHA_Encryptor e_priv(priv_key);

    StringSource ss1(plain, true,
      new PK_EncryptorFilter(rng, e_pub,
        new StringSink(cipher1)
      )
    );

    StringSource ss2(cipher1, true,
      new PK_EncryptorFilter(rng, e_priv,
        new StringSink(cipher2)
      )
    );

    return cipher2;
}

void load(const std::string& filename, BufferedTransformation& bt){
  FileSource file(filename.c_str(), true /*pumpAll*/);

  file.TransferTo(bt);
  bt.MessageEnd();
}

void loadPrivateKey(const std::string& filename, PrivateKey& key){
  ByteQueue queue;

  load(filename, queue);
  key.Load(queue);  
}

void loadPublicKey(const std::string& filename, PublicKey& key){
  ByteQueue queue;

  load(filename, queue);
  key.Load(queue);  
}

And in the main function I call it like this:

std::string encrypted_msg = encryptWithBothKeys("their.pub", "my.key", "0123456789ABCDEF");

Any suggestions?

EDIT: Turns out the ciphertext after the first encryption is size 256. I guess I need to figure out why it's increasing the size.

Upvotes: 1

Views: 637

Answers (1)

jww
jww

Reputation: 102376

I'm not sure why it thinks my messages are 256-bit when they are clearly 128-bit. Below is my code:

Those are bytes, not bits.

What size RSA modulus are you using? I'm guessing its a 2048-bit key, which is 256 bytes, which leaves ≈214 bytes due to OAEP padding.

So the question becomes, what is the size of plain and cipher1 during this:

StringSource ss1(plain, true,
  new PK_EncryptorFilter(rng, e_pub,
    new StringSink(cipher1)
  )
);

My guess is plain1 is small enough. However, when its padded and encrypted, it expands to 256 bytes as cipher1. So the message cipher1 is too large when this is executed:

StringSource ss2(cipher1, true,
  new PK_EncryptorFilter(rng, e_priv,
    new StringSink(cipher2)
  )
);

Also, should the above be using PK_DecryptorFilter? Are you certain you want to encrypt again? If so, then why are you using e_priv?

Encrypting with the private key is not a valid cryptographic operation. If you want the "encrypt with the private key" thing, it usually means you want a Probabilistic Signature Scheme with Recovery (PSSR). Crypto++ supplies a couple of them.

Upvotes: 1

Related Questions