RSA 2048密钥对生成:通过openssl 0.5s通过gpg 30s,为什么会有所不同?


9

RSA 2048密钥对生成:通过openssl 0.5s通过gpg 30s,为什么会有所不同有几个程序可以使RSA公共/私有密钥对生效

例如,GnuPG / OpenPGP有一个通过启动的向导

gpg --gen-key

OpenSSL可以使用这些命令行生成密钥对

openssl genrsa -out testkey.private 2048
openssl rsa -in testkey.private -pubout -out testkey.public

对于同一件事,这就是生成密钥对RSA 2048位,我可以感觉到-在同一台机器上-截然不同的时间。

openssl大约在0.5秒内生成一个密钥对,大约
gpg需要30 秒,甚至广告“移动鼠标以生成随机性/熵”

差异可以解释吗?我知道gpg除了创建RSA密钥外,还做了一些处理,但是我确实选择了选项(4)

请选择您想要哪种钥匙:
   (1)RSA和RSA(默认)
   (2)DSA和Elgamal
   (3)DSA(仅签名)
   (4)RSA(仅签名)
您的选择?

因此,实际上唯一生成的是2048位RSA密钥对。时差却惊人地达到了30秒?

在我看来,要么gpg浪费了不必要的时间,要么OpenSSL没有等待足够的时间,因此创建了不安全的密钥。

我的问题是什么可以解释差异?

更新资料

RSA创建必须以某种随机性为输入。因此,为了确保快速的openssl不仅仅是使用一些存储的随机性的结果,我将其批处理了好几次

time bash -c“对于{1..50}中的i;执行openssl genrsa -out / dev / null 2048;完成;”

产生

真正的0m16.577s
用户0m16.309s
sys 0m0.092s

这就是对于50个2048位RSA密钥(我认为需要大量的熵/随机性),openssl仍然只需要16秒。因此,我的假设是openssl必须被破坏的“答案”。毕竟我不信任我的Linux(3.2.0-59内核)在产生随机性方面变得如此出色。

也许不同之处仅在于openssl /dev/urandom和gpg的使用/dev/random,如果为true可以解释时差,那么我的问题是我不知道如何找到这一点来进行验证。

更新2

为了测试我使用openssl的随机源

strace -xe trace =文件,读取,写入,关闭openssl genrsa -out testkey5.private 2048 2>&1 | grep random -A1

产生

open(“ / dev / urandom”,O_RDONLY | O_NOCTTY | O_NONBLOCK)= 4
读取(4,“ \ x21 \ xd8 \ xaa \ xf1 \ x2b \ x5f \ x4a \ x89 \ x5d \ x6c \ x58 \ x82 \ xc1 \ x88 \ x21 \ x04 \ xfa \ x5b \ x18 \ x98 \ x8 \ x8a \ x34 \ x2b \ xe3 \ xf3 \ xc0 \ xb1 \ xef \ xfb \ x44 \ x15 \ x09“,32)= 32

因此看来,来自32个字节/dev/urandom(不是“更好” /dev/random)足以满足openssl中的2048位RSA密钥对。因此,它是如此之快!

测量

2048位RSA密钥对生成方式

  • 仅32个字节/dev/urandom(使用openssl)
  • 300字节/dev/random(使用openPGP GNU Privacy Guard)

这当然可以解释时差!

Answers:


10

/dev/random对于实际使用的每个随机字节,GnuPG都会消耗几个字节。您可以使用以下命令轻松检查:

start cmd:> strace -e trace=open,read gpg --armor --gen-random 2 16 2>&1 | tail
open("/etc/gcrypt/rngseed", O_RDONLY)   = -1 ENOENT (No such file or directory)
open("/dev/urandom", O_RDONLY)          = 3
read(3, "\\\224F\33p\314j\235\7\200F9\306V\3108", 16) = 16
open("/dev/random", O_RDONLY)           = 4
read(4, "/\311\342\377...265\213I"..., 300) = 128
read(4, "\325\3\2161+1...302@\202"..., 172) = 128
read(4, "\5[\372l\16?\...6iY\363z"..., 44) = 44
open("/home/hl/.gnupg/random_seed", O_WRONLY|O_CREAT, 0600) = 5
cCVg2XuvdjzYiV0RE1uzGQ==
+++ exited with 0 +++

为了输出16个字节的高质量熵,GnuPG从中读取300个字节/dev/random

此处说明:随机数子系统体系结构

Linux最多存储4096个字节cat /proc/sys/kernel/random/poolsize的熵(请参阅参考资料)。如果一个进程需要的资源超过可用的资源(请参阅参考资料cat /proc/sys/kernel/random/entropy_avail),那么随着内核熵池的馈入速度成为相关因素,CPU使用率变得无关紧要。


令人印象深刻。感谢您的见解。我认为这个问题很有启发性!因此,即使openssl对32 /dev/urandom字节质量较低的gpg 感到满意,甚至说“ 1字节/dev/random不足以容纳1字节随机数”。难道不意味着与gpg相比,openssl键更倾向于“随机性太小”?
humanityANDpeace

1
@humanityANDpeace随机性是一个无休止的讨论。不久前,该站点的“主用户”声称/dev/urandom对于加密目的已经足够了。在GnuPG邮件列表上,他可能会因此而被嘲笑。AFAIK不可能证明某些数据是纯粹随机的。您可以找到非随机性,但只能找到完全符合该模式的地方。
Hauke Laging

是的,我看到:)还是那个的GPG使用300bytes的事实/dev/random,而OpenSSL的用途只有32字节的/dev/urandom似乎暗示了如何想要一个2048位RSA密钥的用户谨慎潜在的安全风险。因此,我会选择gpg。32字节似乎awefully小
humanityANDpeace

2
@HaukeLaging该站点的“主用户”从信息安全密码学的“主用户”那里得到了建议,并给出了有意义的解释(与Linux的熵池大小计算不同)。来自/ dev / urandom的兰特对于登录密钥是否安全?简短的回答是。长答案也是。”
吉尔斯(Gilles)'“ SO-不要邪恶”

2
从种子良好的CSPRNG中读取的32个字节可提供256位安全性(真是该死)。RSA-2048位密钥仅提供约112位安全性。a的唯一可疑属性/dev/urandom是(在linux上)它不会在启动后直接成为种子之前阻塞。一旦播种,它将永远保持安全。
CodesInChaos 2014年

7

您的建议是,这种差异是因为openssl使用/ dev / urandom而gpg使用/dev/random是正确的。

您可以使用以下命令查看生成密钥时可用的熵下降gpg

watch -n 1 cat /proc/sys/kernel/random/entropy_avail

我使用了一个程序来生成有关使用设置OpenGPG智能卡gpg的步骤的描述,因此我不得不运行gpg多次,直到所有操作都按预期进行。初始运行后,我注意到/dev/random它将没有足够的熵,并且gpg会停滞不前,等待新的熵累积。

我写了一个小程序来提供额外的非随机数据,这样做gpg不会“暂停”,而是几乎立即生成了密钥:很适合测试脚本是否正确运行,但是在生成真实的脚本时当然不应该做键。

该程序加快了速度gpg在实际情况下请勿使用):

# For testing purposes only 
# DO NOT USE THIS, tHIS DOES NOT PROVIDE ENTROPY TO /dev/random

import fcntl
import time
import struct

RNDADDENTROPY=0x40085203

while True:
    random = "3420348024823049823-984230942049832423l4j2l42j"
    t = struct.pack("ii32s", 8, 32, random)
    with open("/dev/random", mode='wb') as fp:
        # as fp has a method fileno(), you can pass it to ioctl
        res = fcntl.ioctl(fp, RNDADDENTROPY, t)
        time.sleep(0.001)

当我边观察边运行时,entropy_avail可以看到可用熵超过3800。


感谢您的回答。我仍然期待测试gpg,但遗憾的是它不太容易批处理,而且更具交互性。..仍然。您确定cat本身的重复呼叫还没有耗尽熵吗?您是否有证据或消息来源告诉gpg使用/dev/random可以完善答案的方法?最后,这是否还意味着openssl生成的质量比gqg低的RSA密钥对?
humanityANDpeace

@humanityANDpeace可以(虽然不太明显)在批处理模式下使用GnuPG。Unattended key generation在文件中搜索/usr/share/doc/packages/gpg2/DETAILS(或在发行版中进行搜索)。该/dev/random证据是我的答案。
Hauke Laging

@humanityANDpeace Hauke的答案更多地是当场,但在研究如何设置OpenGPG卡时,我找到了一些参考。配料是不平凡的,但我已经使用了Python程序我已经可以用到位桶
安森

我既喜欢答案,也喜欢提出正确的解决方案。感谢您的链接bitbucket!
humanityANDpeace

1
产生一个新进程会消耗熵,因此更好的方法是使用read内置的shell:while read -r < /proc/sys/kernel/random/entropy_avail; do clear; date; printf '\nAvailable entropy: %s bytes\n' "$REPLY"; sleep 1; done
nyuszika7h 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.