- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在尝试使用公钥加密消息并使用私钥解密密码,在 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;
}
我的问题:
按照 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.
请注意... GlobalRNG
是 Test
命名空间的一部分。它在 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/
我有一个问题,但由于 this question 部分正在解决,但我想知道如何计算给定间隔之间的天数。 这是一个计算员工休假天数的查询。所以给定(或不给定)一个日期范围,我想计算给定间隔之间有多少假期
变量dateSubtract结果是 16,但我想找到这 2 天之间的总天数,应该是 165。没有 JODA TIME 我该如何做到这一点? String date = "06/17/2014"; Da
我想选择创建日期介于给定月份的第一天和最后一天之间的记录。我通过以下方式计算开始日期和结束日期的月份: 日期“月份”只是时间范围内的随机日期 Calendar cal = Calendar.getIn
我有一个对你们大多数人来说可能微不足道的问题。我尝试了很多,没有找到解决方案,所以如果有人能给我提示,我会很高兴。起点是每周 xts -时间序列。 月周值(value)目标 2011 年 12 月 W
我有一个 Facebook 应用程序,它将用户生日作为 varchar 存储在 mysql 数据库中。我正在尝试获取所有用户的生日 1周后推出,如果是在本周如果生日是上周。 在我的 php 中,我获取
我正在使用以下代码来获取年、月、日中的两个日期之间的差异 tenAppDTO.getTAP_PROPOSED_START_DATE()=2009-11-01 tenAppDTO.getTAP_PRO
我想检查当前时间(在 C++ 中)是否在一个时间范围内。 我想从元组 ("12:00", "17:30") 构造时间范围,即 (string, string) 并检查时间 now() 是否介于两者之间
gitlab 有一个功能,如果我在提交消息中放入票号,那么提交将与 gitlab.com 上的票相关联。 这在进行代码审查时非常方便。不幸的是,开发人员有时会忘记这样做。 我想指定 git hooks
我正在尝试制作使用SQLite数据库的简单注册/登录应用程序,到目前为止我得到了这段代码。这是我的“注册” Activity ,我猜它应该在按下注册按钮后将用户名和 pin(密码)实现到数据库,遗憾的
我正在尝试打开、关闭和写入文件。每当我尝试打开一个文件时,如果我提供的路径中不存在该文件,程序就会告诉我。如果存在,程序将读取其中的内容并显示它。如果用户不想查找文件,可以选择创建文件并用数据填充它。
我想要我的至slideToggle每当发生 react 性变化时,但到目前为止我还无法使其发生。我尝试在 rendered 中使用 JQuery和created模板的事件,但它没有触发。 触发此操作的
我们的 MySQL 遇到了神秘的网络问题。简单的更新查询(使用索引更新单行)通常会立即运行,然后有时(假设 1000 次中有 1 次)因超时而失败。与简单的插入查询相同。数据库没有过载。我们怀疑网络问
我正在使用 actionbarsherlock 的 ActionBar,第一次以横向或水平方向运行应用程序时,选项卡以 Tabs Mode 显示。将方向更改为纵向后,导航模式仍在 Tabs 中。第二次
每天晚上(太平洋标准时间晚上 8 点)我都会对生产数据库(innoDB 引擎)进行全局备份。 这是 mysqldump 命令: mysqldump -u$MYSQLUSER -p$MYSQLPWD -
当我的应用程序第一次启动时,它应该显示用户协议(protocol),这是一个 59kb 的 txt 文件。由于读取文件并将其附加到 TextView 需要一些时间,因此我决定在异步任务中执行此操作并在
如何只允许一个“.”在按键期间的javascript中? 我这里有一个代码: function allowOneDot(txt) { if ((txt.value.split(".")
我已经创建了像主页和用户这样的标题图标。在桌面 View 中,如果我单击用户图像,它会显示相应的重定向页面。如果我在选项卡或移动 View 中将其最小化, 它什么都不显示。此问题仅发生在用户图像上,而
下面的代码在 Release模式下工作,并且仅在 Debug模式下在 g_ItemList.push_back() 引发错误,我浏览了一些 SO 帖子和论坛。有人提到 "You can't itera
我遇到了一个我似乎无法解决的 mmap 问题。下面是设置:我使用 malloc 将一个巨大的多维数组分配到内存中,用我的值填充它,然后我想将它保存在一个文件中。该数组包含 3200000000 个字节
尝试加载共享库: handle = dlopen( "libaaa.so.2.5", RTLD_NOW ); if ( !handle ) { printf("Failed t
我是一名优秀的程序员,十分优秀!