gpt4 book ai didi

c++ - RSA加密和解密期间的RandomNumberGenerator要求?

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:59:52 25 4
gpt4 key购买 nike

我正在尝试使用公钥加密消息并使用私钥解密密码,在 shell 中使用 crypto++ 就像这样:

openssl rsautl -encrypt -inkey id_rsa.pub.pem -pubin -in message -out message.enc

openssl rsautl -decrypt -inkey id_rsa.pem -in message.enc -out message.dec

加密/解密在单独的应用程序中完成。我从 https://www.cryptopp.com/wiki/RSA_Cryptography 的例子开始.我的代码:

std::string publicEncrypt(std::string const& plain) {
auto cipher = std::string{};
CryptoPP::RSAES_OAEP_SHA_Encryptor e(getPublicKey());
CryptoPP::StringSource(plain, true,
new CryptoPP::PK_EncryptorFilter(CryptoPP::NullRNG(), e,
new CryptoPP::StringSink(cipher)));
return cipher;
}

std::string privateDecrypt(std::string const& cipher) {
auto decrypted = std::string{};
CryptoPP::RSAES_OAEP_SHA_Decryptor d(getPrivateKey());
CryptoPP::StringSource(cipher, true,
new CryptoPP::PK_DecryptorFilter(CryptoPP::NullRNG(), d,
new CryptoPP::StringSink(decrypted)));
return decrypted;
}

我的问题:

  1. 为什么 EncryptorFilter/DecryptorFilter 需要随机数生成器 (RNG)?
  2. 加密/解密的 RNG 必须相同,对吗?那么,进程之间如何共享呢?

按照 https://stackoverflow.com/users/608639/jww 的建议使用 NullRNG()在 Unable to do RSA Encrption/Decryption using Crypto++ (isValidCoding is false)导致

std::exception NullRNG: NullRNG should only be passed to functions that don't need to generate random bytes.

我想我从根本上错过了一些东西。感谢提示和建议。

如果我在具有全局 RNG 的单元测试中使用此代码,一切正常。

最佳答案

Why is a random number generator (RNG) needed for EncryptorFilter/DecryptorFilter?

签名和验证类是 cryptlib.h 中设置的抽象接口(interface).有些密码系统使用它们,有些则不使用。一个类将专门化并且可以放弃使用生成器。有时一个类不需要生成器来执行其中一个操作。如果不需要,可以使用 NullRNG

RSA 在公钥操作期间需要 RNG 的原因是消息填充。填充通常是消息格式化功能的一部分。正如@PuzzlePalace 指出的那样,OAEP 填充是随机的而不是确定性的。

RSA 在私钥操作期间需要 RNG 的原因是盲目的。对于 RSA 和其他类似 RSA 的方案(如 Rabin-Williams),盲化只是乘以一个随机值以掩盖私钥的反转以恢复原始值。之后,在签名或解密后,去除盲值,保留运算结果。

相关的,DSA 或 ECDSA 在私钥操作期间需要 RNG 的原因是 RFC 6979, Deterministic Usage of the Digital Signature Algorithm (DSA) and Elliptic Curve Digital Signature Algorithm (ECDSA) .确定性签名不使用随机格式或随机 k

公钥和私钥操作需要 RNG 的另一个原因是对 key 进行验证检查。例如,可能会检查一个键以确保特定约束成立,例如它的质数或它具有特定的 Jacobi 符号。


The RNG has to be the same for encryption/decryption, right? So, how to share between processes?

不,生成器可以不同。唯一的要求是它们产生一个随机流,以便对“随机”的含义进行一些合理的定义。没有 split 太多头发,这意味着生成器产生均匀分布。

您可以在 RandomNumberGenerator 找到更多关于 Crypto++ 生成器的阅读资料在维基上。


If I use this code in a unit test with a global RNG, everything works fine.

请注意... GlobalRNGTest 命名空间的一部分。它在 test.cpp : 115 中定义:

NAMESPACE_BEGIN(CryptoPP)
NAMESPACE_BEGIN(Test)

ANONYMOUS_NAMESPACE_BEGIN
OFB_Mode<AES>::Encryption s_globalRNG;
NAMESPACE_END

RandomNumberGenerator & GlobalRNG()
{
return dynamic_cast<RandomNumberGenerator&>(s_globalRNG);
}

NAMESPACE_END // Test
NAMESPACE_END // CryptoPP

GlobalRNG 是一个确定性生成器,它不是库本身的一部分。如果您依赖它,您的代码将无法在现场编译。

使用在 RandomNumberGenerator 中讨论的其他生成器之一在维基上。 AutoSeededRandomPool 是一个不错的选择。


Using the NullRNG() as recommended by https://stackoverflow.com/users/608639/jww in Unable to do RSAEncrption/Decryption using Crypto++ (isValidCoding is false) leads to

std::exception NullRNG: NullRNG should only be passed to functions that don't need to generate random bytes.

该信息不正确。我需要修理它。谢谢。


有趣的是(以一种病态的方式),Crypto++ 占用了 CVE-2015-2141由于 Rabin-Williams 致盲。致盲值必须是二次余数;否则攻击者可以准备特殊消息来泄露私钥。

叶夫根尼·西多罗夫 (Evgeny Sidorov) 的完整论文可在 Breaking the Rabin-Williams digital signature system implementation in the Crypto++ library 获取。 .这是修复 Sidorov 攻击后新的和改进的反函数的样子(来自 rw.cpp ):

ModularArithmetic modn(m_n), modp(m_p), modq(m_q);
Integer r, rInv;

do
{
// Do this in a loop for people using small numbers for testing
r.Randomize(rng, Integer::One(), m_n - Integer::One());
// Fix for CVE-2015-2141. Thanks to Evgeny Sidorov for reporting.
// Squaring to satisfy Jacobi requirements suggested by Jean-Pierre Munch.
r = modn.Square(r);
rInv = modn.MultiplicativeInverse(r);
} while (rInv.IsZero());

如果您阅读 Sidorov 论文的第 6 节,他建议生成一个随机 r,然后检查 r 的雅可比符号以确保其为二次剩余。如果它不是 QR,则尝试一个新的随机 r。分类使用了该方法,但它表明该方案的速度大大降低,因为随机 r 以 1/16 的概率满足条件。

但是,我们知道 r 的平方确保我们在第一次尝试时就满足 Jacobi,因为 r2 mod n 始终是二次剩余。平方/乘法只需要 log (exp)(而不是 n log (n)),因此经过反复试验证明这是一个显着的加速。在我们发布下一个版本的库之前,我们切换到平方方法。

关于c++ - RSA加密和解密期间的RandomNumberGenerator要求?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44680703/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com