无法使用 Crypto++ 进行 RSA 加密/解密(isValidCoding 为 false) [英] Unable to do RSA Encryption/Decryption using Crypto++ (isValidCoding is false)
问题描述
我正在使用 Crypto++ 使用 RSA 加密字节数组.我遵循了 Crypto++ wiki 的示例,但没有成功让它们工作.所有样本中的加密和解密都是在一个进程中完成的,但我试图解密已经在另一个进程中加密的内容.这是我的代码:
I am using Crypto++ to encrypt an array of bytes using RSA. I have followed Crypto++ wiki's samples with no luck getting them to work. 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 );
}
不幸的是,isValidCoding 的值为 false.我想我对 RSA 加密/解密有一些误解!!
请注意,已使用 KEY.Validate(prng, 3) 验证了 privKey 和 pubKey.我也尝试过使用 RAW RSA 而不是 OAEP 和 SHA,但没有成功.我试图通过 crypto++ 代码进行调试,我怀疑的是 prng 变量.我认为它有问题.我也使用了 AutoSededRandomPool 而不是 FixedRNG 但它没有帮助.
值得知道的是,如果我在加密代码之后复制解密代码并在 Encrypt() 方法中执行它,一切都很好并且 isValidCoding 是真的!!
Unfortunately, value of isValidCoding is false. I think I am misunderstanding something about RSA encryption/decryption!!
Note that, privKey and pubKey have been validated using KEY.Validate(prng, 3).
I have also tried to use RAW RSA instead of OAEP and SHA with no luck. I have tried to debug through crypto++ code, what I am suspicious about is prng variable. I think there is something wrong with it. I have also used AutoSeededRandomPool instead of FixedRNG but it didn't help.
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!!
推荐答案
这可能不正确:
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
.
You should probably be calling CiphertextLength
on plaintext
.
我不太确定你是如何从 encrypt()
返回一个 uint_t
的.
I'm not really sure how you are just returning an uint_t
from encrypt()
.
重新开始,并使用 Crypto++ 中的示例作为起点,您可能会做得更好.我不确定这个设计是否值得追求.
You might do better by starting fresh, and using an example from the Crypto++ as a starting point. I'm not sure this design is worth pursuing.
如果您重新开始,那么 Shoup 的椭圆曲线集成加密方案 (ECIES) 将是一个不错的选择,因为它将公钥与对称密码和身份验证标签相结合.
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.
这篇关于无法使用 Crypto++ 进行 RSA 加密/解密(isValidCoding 为 false)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!