Cannot perform RSA Encrption / Decryption using Crypto ++ (isValidCoding is false)

I am using Crypto ++ to encrypt a byte array using RSA. I have followed the Crypto ++ wiki examples and you have no luck getting them to work. Encryption and decryption in all samples is done in the same process, but I am trying to decrypt content that is already encrypted in another process. Here is my code:

class FixedRNG : public CryptoPP::RandomNumberGenerator
{
public:
    FixedRNG(CryptoPP::BufferedTransformation &source) : m_source(source) {}

    void GenerateBlock(byte *output, size_t size)
    {
        m_source.Get(output, size);
    }

private:
    CryptoPP::BufferedTransformation &m_source;
};


uint16_t Encrypt()
{
    byte *oaepSeed = new byte[2048];
    for (int i =  0; i < 2048; i++)
    {
        oaepSeed[i] = (byte)i;
    }
    CryptoPP::ByteQueue bq;
    bq.Put(oaepSeed, 2048);
    FixedRNG prng(bq);
    Integer n("Value of N"),
    e("11H"),
    d("Value of D");
    RSA::PrivateKey privKey;
    privKey.Initialize(n, e, d);
    RSA::PublicKey pubKey(privKey);
    CryptoPP::RSAES_OAEP_SHA_Encryptor encryptor( pubKey );
    assert( 0 != encryptor.FixedMaxPlaintextLength() );
    byte blockSize = encryptor.FixedMaxPlaintextLength();
    int divisionCount = fileSize / blockSize;
    int proccessedBytes = 0;
    // Create cipher text space
    uint16_t cipherSize = encryptor.CiphertextLength( blockSize );
    assert( 0 != cipherSize );

    encryptor.Encrypt(prng, (byte*)plaintext, blockSize, (byte*)output);
    return cipherSize;
}

void Decrypt(uint16_t cipherSize)
{
        byte *oaepSeed = new byte[2048];
        for (int i =  0; i < 2048; i++)
        {
            oaepSeed[i] = (byte)i;
        }
        CryptoPP::ByteQueue bq;
        bq.Put(oaepSeed, 2048);
        FixedRNG prng(bq);
        Integer n("Value of N"),
        e("11H"),
        d("Value of D");
        RSA::PrivateKey privKey;
        privKey.Initialize(n, e, d);
        //RSA::PublicKey pubKey(privKey);

        CryptoPP::RSAES_OAEP_SHA_Decryptor decryptor( privKey );

        byte blockSize = decryptor.FixedMaxPlaintextLength();
        assert(blockSize != 0);

        size_t maxPlainTextSize = decryptor.MaxPlaintextLength( cipherSize );
        assert( 0 != maxPlainTextSize );
        void* subBuffer = malloc(maxPlainTextSize);
        CryptoPP::DecodingResult result = decryptor.Decrypt(prng, (byte*)cipherText, cipherSize, (byte*)subBuffer);
        assert( result.isValidCoding );
        assert( result.messageLength <= maxPlainTextSize );
}

      

Unfortunately, the isValidCoding value is false. I think I don't understand something about RSA encryption / decryption !!
Note that privKey and pubKey were validated using KEY.Validate (prng, 3). I've also tried using RAW RSA instead of OAEP and SHA with no luck. I tried to debug the crypto ++ code, which I am suspicious of the prng variable . I think there is something wrong with that. I also used AutoSeededRandomPool instead of FixedRNG, but that didn't help.
It's worth knowing that if I copy the decryption code right after the encryption code and execute it in the Encrypt () method, everything is fine and isValidCoding is correct !!

+1


source to share


1 answer


This may not be correct:

byte blockSize = encryptor.FixedMaxPlaintextLength();
...

encryptor.Encrypt(prng, (byte*)plaintext, blockSize, (byte*)output);
return cipherSize;

      

Try:

size_t maxLength = encryptor.FixedMaxPlaintextLength();
size_t cipherLength = encryptor.CiphertextLength( blockSize );
...

SecureByteBlock secBlock(cipherLength);

cipherLength = encryptor.Encrypt(prng, (byte*)plaintext, blockSize, secBlock);
secBlock.resize(cipherLength);

      

FixedMaxPlaintextLength

returns a size_t

, not byte

.



You should probably be calling CiphertextLength

on plaintext

.

I'm not sure how you just return uint_t

from encrypt()

.

You can do it better by starting from scratch and using the example from Crypto ++ as a starting point. I'm not sure if this design is worth it.

If you're starting over, the Shoup Elliptic Curve (ECIES) integrated encryption scheme is a good choice as it combines the public key with symmetric ciphers and authentication tags.

0


source







All Articles