我使用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而没有运气。我试图通过crypto ++代码进行调试,我怀疑的是 prng 变量。我觉得它有问题。我也使用了AutoSeededRandomPool而不是FixedRNG但它没有帮助。
值得知道的是,如果我在加密代码之后立即复制解密代码并在Encrypt()方法中执行它,一切都很好并且isValidCoding为true !!
答案 0 :(得分:0)
这可能不正确:
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
。
您应该在CiphertextLength
上致电plaintext
。
我不确定你是如何从uint_t
返回encrypt()
的。
你可以通过开始新鲜,并使用Crypto ++中的一个例子作为起点来做得更好。我不确定这个设计值得追求。
如果你重新开始,那么Shoup的椭圆曲线集成加密方案(ECIES)将是一个不错的选择,因为它将公钥与对称密码和认证标签结合起来。