简体   繁体   English

无法使用Crypto ++执行RSA加密/解密(isValidCoding为false)

[英]Unable to do RSA Encryption/Decryption using Crypto++ (isValidCoding is false)

I am using Crypto++ to encrypt an array of bytes using RSA. 我正在使用Crypto ++使用RSA加密字节数组。 I have followed Crypto++ wiki's samples with no luck getting them to work. 我没有遵循Crypto ++ wiki的示例,也没有运气。 Encryption and Decryption in all the samples are done within a single process but I am trying to decrypt the content which 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, value of isValidCoding is false. 不幸的是,isValidCoding的值为false。 I think I am misunderstanding something about RSA encryption/decryption!! 我想我对RSA加密/解密有误解!
Note that, privKey and pubKey have been validated using KEY.Validate(prng, 3). 请注意,已使用KEY.Validate(prng,3)验证了privKey和pubKey。 I have also tried to use RAW RSA instead of OAEP and SHA with no luck. 我也曾尝试使用RAW RSA而不是OAEP和SHA,但是没有运气。 I have tried to debug through crypto++ code, what I am suspicious about is prng variable. 我试图通过crypto ++代码进行调试,但我怀疑的是prng变量。 I think there is something wrong with it. 我认为这有问题。 I have also used AutoSeededRandomPool instead of FixedRNG but it didn't help. 我还使用了AutoSeededRandomPool而不是FixedRNG,但这没有帮助。
Worth to know that, if I copy the decryption code right after encryption code and execute it in Encrypt() method, everything is fine and isValidCoding is true!! 值得知道的是,如果我在加密代码之后立即复制解密代码并在Encrypt()方法中执行它,那么一切都很好,并且isValidCoding是真实的!

This is probably 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 a byte . FixedMaxPlaintextLength返回size_t ,而不是byte

You should probably be calling CiphertextLength on plaintext . 您可能应该在plaintext上调用CiphertextLength

I'm not really sure how you are just returning an uint_t from encrypt() . 我不太确定你是怎么从uint_t encrypt()返回uint_t

You might do better by starting fresh, and using an example from the Crypto++ as a starting point. 从头开始,并以Crypto ++中的示例为起点,可能会做得更好。 I'm not sure this design is worth pursuing. 我不确定这种设计是否值得追求。

If you start over, then Shoup's Elliptic Curve Integrated Encryption Scheme (ECIES) would be a good choice since it combines public key with symmetric ciphers and authentication tags. 如果您重新开始,那么Shoup的椭圆曲线集成加密方案(ECIES)将是一个不错的选择,因为它结合了带有对称密码和身份验证标签的公钥。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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