1024 位 RSA 密钥对的 DER 编码的 RSAPublicKey (PKCS #1) 长度是否一致?

0 openssl rsa asn.1 pkcs#1

我使用 openssl 命令创建了多个 1024 位 DER 编码的 RSAPublicKeys (PKCS #1):

openssl genrsa 1024 | openssl rsa -outform DER -RSAPublicKey_out -out pubkey.der
Run Code Online (Sandbox Code Playgroud)

到目前为止,每个这样创建的公钥文件正好有 140 个字节。以这种格式编码的 1024 位 RSA 公钥是否始终为 140 字节,或者该大小是否可以变化?

我了解到 DER 编码私钥的大小可能会有所不同。

bar*_*njs 5

对于使用指数值 F4 (0x010001) 的 1024 位密钥,它应始终为 140 字节。

公钥的编码是

SEQUENCE (RSAPublicKey)
30 xa [ya [za ...]]
   INTEGER (n)
   02 xb [yb [zb ...]] [pb] ...
   INTEGER (e)
   02 xc [yc [zc ...]] [pc] ...
Run Code Online (Sandbox Code Playgroud)

其中pbpc是可选的填充字节(以防止整数为负数),xa-xc(和 y/za-c)值是 BER 长度。

如果 e 为 0x010001,则它编码为02 03 01 00 01,始终为 5 个字节。

RSA 密钥的密钥大小由从第一个设置位开始的位串的长度确定。因此,对于 1024 位密钥,该值将在 2^1023 和 2^1024 之间,并且它看起来像

0b1xxx_xxxx {1016 other "don't care" bits}
Run Code Online (Sandbox Code Playgroud)

由于设置了高位,如果没有填充,该数字将为负数,因此 1024 位数字被编码为 128 个值字节和一个“符号位未设置”的前导字节,即 129 个字节。

现在我们知道了整数的完整编码长度,129。这是十六进制的 0x81,它比 0x79(最大的“紧凑”BER 长度)大,所以长度以长形式写入:0x81(长度在下一个中表示) 1 字节)0x81。

02 81 81 00 [128 more bytes representing n]
Run Code Online (Sandbox Code Playgroud)

所以e编码为5个字节,n编码为132(128+1+2+1),即137。

137 的十六进制为 0x89,使得序列长度为 0x81 0x89。137 字节内容 + 2 字节长度 + 1 字节标签 => 140 字节。

30 81 89
   02 81 81 00 [128 more bytes of n]
   02 03 01 00 01
Run Code Online (Sandbox Code Playgroud)

这一计算假设没有人对密钥大小的定义有问题。宽松的解释(根据http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-56Br1.pdf是错误的)会将 的值置于n2^1016 和 2^1024 之间(又名“it需要 128 个字节,谁关心哪一位是最高位呢?”)。在这种情况下,填充字节可能会消失n,长度将降至 139。