【问题标题】:Unable to do RSA Encryption/Decryption using Crypto++ (isValidCoding is false)无法使用 Crypto++ 进行 RSA 加密/解密(isValidCoding 为假)
【发布时间】:2013-06-10 16:18:58
【问题描述】:

我正在使用 Crypto++ 使用 RSA 加密字节数组。我一直关注 Crypto++ wiki 的示例,但没有让它们正常工作。所有样本中的加密和解密都是在一个进程中完成的,但我试图解密已经在另一个进程中加密的内容。 这是我的代码:

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

不幸的是,isValidCoding 的值为 false。我想我对 RSA 加密/解密有误解!!
请注意,privKey 和 pubKey 已使用 KEY.Validate(prng, 3) 进行了验证。 我也尝试过使用 RAW RSA 而不是 OAEP 和 SHA,但没有成功。我试图通过加密++代码进行调试,我怀疑的是 prng 变量。我认为它有问题。我也使用了 AutoSeedRandomPool 而不是 FixedRNG,但它没有帮助。
值得知道的是,如果我在加密代码之后立即复制解密代码并在 Encrypt() 方法中执行它,一切都很好,并且 isValidCoding 是真的! !

【问题讨论】:

  • 您需要更仔细地调试它。我找不到代码的任何直接错误。为什么void* subBuffer = malloc(maxPlainTextSize);
  • 亲爱的@CaptainGiraffe,感谢您的评论。我已经调试了一个多星期。除非我尝试了所有我能想到的方法,否则我通常会犹豫在 StackOverflow 上提问。在 RSA 解密中,在解密完成之前我们不知道明文的确切长度,因此我们必须创建一个大小为 decryptor.MaxPlaintextLength(cipherSize) 的缓冲区,然后将其修剪为 result.messageLength。该代码最烦人的是,当我在加密发生的地方复制并粘贴它时它成功运行!
  • 以下是您可能想要查看的参考:cryptopp.com/wiki/RSA_Encryption_Schemes
  • @noloader 感谢您的评论。好吧,我并没有说代码是从 wiki 复制粘贴的,我确实修改了示例以符合我的要求。我没有在这个问题中包含 n 和 d 的值,但准确地说,我使用的是 384 位值。如果未验证密钥,我正在使用if(!publicKey.Validate(prng, 3)) 引发错误。感谢 NullRNG 的建议,我会试一试。我还将按照您给定链接中的示例进行操作。

标签: c++ rsa public-key-encryption crypto++


【解决方案1】:

这可能是不正确的:

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

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

试试:

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 返回 size_t,而不是 byte

您可能应该在plaintext 上致电CiphertextLength

我不确定你是如何从encrypt() 返回一个uint_t

从新开始,并使用 Crypto++ 中的示例作为起点,您可能会做得更好。我不确定这种设计是否值得追求。

如果您重新开始,那么 Shoup 的椭圆曲线集成加密方案 (ECIES) 将是一个不错的选择,因为它将公钥与对称密码和身份验证标签结合在一起。

【讨论】:

    猜你喜欢
    • 2012-04-07
    • 1970-01-01
    • 2018-06-26
    • 2014-11-10
    • 2013-11-06
    • 1970-01-01
    • 2017-07-02
    • 2012-05-08
    • 2021-11-04
    相关资源
    最近更新 更多