我使用的是OpenSSL 1.0.2版
$ openssl version
OpenSSL 1.0.2j 26 Sep 2016
我为学习目的生成一个32位密钥:
$ openssl genrsa -out key.pem 32; openssl rsa -in key.pem -text -noout
Generating RSA private key, 32 bit long modulus
.+++++++++++++++++++++++++++
.+++++++++++++++++++++++++++
e is 65537 (0x10001)
Private-Key: (32 bit)
modulus: 3049905109 (0xb5c9dbd5)
publicExponent: 65537 (0x10001)
privateExponent: 643259637 (0x26575cf5)
prime1: 59747 (0xe963)
prime2: 51047 (0xc767)
exponent1: 34201 (0x8599)
exponent2: 28991 (0x713f)
coefficient: 570 (0x23a)
我测试了59747 * 51047 == 3049905109,所以这是正确的。
然后我尝试生成128位:
$ openssl genrsa -out key.pem 128; openssl rsa -in key.pem -text -noout
Generating RSA private key, 128 bit long modulus
.....+++++++++++++++++++++++++++
.+++++++++++++++++++++++++++
e is 65537 (0x10001)
Private-Key: (128 bit)
modulus:
00:d7:f5:7b:f4:ac:b3:d6:ab:69:e9:f8:46:89:80:
ad:a7
publicExponent: 65537 (0x10001)
privateExponent:
00:96:69:0e:9d:5a:0f:a3:49:d5:f2:7f:5b:d5:bd:
d5:71
prime1: 4077820879 (0xf30e9bcf)
prime2: 1063358121 (0x3f618ea9)
exponent1: 843651503 (0x324919af)
exponent2: 245467033 (0xea18799)
coefficient: 3957324193 (0xebdff9a1)
显然0xf30e9bcf * 0x3f618ea9 = 3C2D38538980ADA7,但模数为00d7f57bf4acb3d6ab69e9f8468980ada7。
看起来最后8个十六进制数字是正确的,但其他数字不一样。我很困惑为什么会这样。有人可以解释一下吗?
答案 0 :(得分:2)
打印命令似乎已经混淆了,它将prime1
和prime2
(和朋友)打印为32位值而不是64位值。
factorization of D7F57BF4ACB3D6AB69E9F8468980ADA7
为F798F9F1F30E9BCF
* DF49A5063F618EA9
。
OpenSSL命令打印了每个素数因子的底部32位,而不是全部64位。
由于此乘法中没有mod,结果的底部32位对于修剪值是正确的,这仅仅是由于乘法。 (回想一下,用长格式写出两个长数的乘法......现在用十六进制表示。)
我运行了很多次命令,它总是打印CRT值的64位值:
$ openssl genrsa 128 | openssl rsa -text
Generating RSA private key, 128 bit long modulus
.+++++++++++++++++++++++++++
...+++++++++++++++++++++++++++
e is 65537 (0x10001)
Private-Key: (128 bit)
modulus:
00:e9:e2:0f:ed:54:89:0c:e7:4c:a0:c5:52:8f:c3:
85:c3
publicExponent: 65537 (0x10001)
privateExponent:
00:b5:bc:a8:dd:a5:3b:9d:9e:bd:80:57:b6:b2:ff:
f3:d1
prime1: 17667776196693030377 (0xf5308cd7cefd75e9)
prime2: 17596097080145549003 (0xf431e510f75d16cb)
exponent1: 10532946027144870681 (0x922c8a9b1254fb19)
exponent2: 7661660226727396529 (0x6a53af620bd344b1)
coefficient: 1528899226626897395 (0x1537bdbf047735f3)
writing RSA key
-----BEGIN RSA PRIVATE KEY-----
MGMCAQACEQDp4g/tVIkM50ygxVKPw4XDAgMBAAECEQC1vKjdpTudnr2AV7ay//PR
AgkA9TCM1879dekCCQD0MeUQ910WywIJAJIsipsSVPsZAghqU69iC9NEsQIIFTe9
vwR3NfM=
-----END RSA PRIVATE KEY-----
进一步深入研究,当long
仍然是32位时,看起来问题发生在64位系统上。
https://github.com/openssl/openssl/blob/OpenSSL_1_0_2j/crypto/asn1/t_pkey.c#L82-L87:
if (BN_num_bytes(num) <= BN_BYTES) {
if (BIO_printf(bp, "%s %s%lu (%s0x%lx)\n", number, neg,
(unsigned long)num->d[0], neg,
(unsigned long)num->d[0])
<= 0)
return (0);
在配置期间定义SIXTY_FOUR_BIT_LONG or SIXTY_FOUR_BIT的系统上, BN_BYTES
为8。
$ grep SIXTY_FOUR `locate opensslconf.h | grep ^/usr`
#define SIXTY_FOUR_BIT_LONG
#undef SIXTY_FOUR_BIT
因为我SIXTY_FOUR_BIT_LONG
我的打印命令适用于33到64位范围。
$ uname -srmo
Linux 4.4.0-119-generic x86_64 GNU/Linux
$ head -2 /etc/os-release
NAME="Ubuntu"
VERSION="16.04.4 LTS (Xenial Xerus)"