【问题标题】:What is the maximum length of private and public RSA keys?RSA 私钥和公钥的最大长度是多少?
【发布时间】:2016-12-28 08:27:00
【问题描述】:

我在 PHP 中使用 OpenSSL 生成私钥和公钥,我打算将它们存储在数据库中(尽管您可能不需要了解 PHP 来回答这个问题)。

它们看起来像这样:

-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIi4rlLSKA9/8CAggA
...
-----END ENCRYPTED PRIVATE KEY-----

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8YvAFZHSGNITeDNdXFbc
...
-----END PUBLIC KEY-----

(是的,这些只是示例)

它们是这样创建的:

$resource = openssl_pkey_new([
        'private_key_bits' => '2048',
        "private_key_type" => OPENSSL_KEYTYPE_RSA,
]);
openssl_pkey_export($resource, $privateKey, $passPhrase) === false
$opensslDetails = openssl_pkey_get_details($resource);
$publicKey = $opensslDetails['key'];

我想知道这些私钥和公钥的最大长度是多少。

从我的实验中,我发现:

  • 1704 个字符的私钥
  • 1834 个字符的私钥和密码
  • 451 个字符的公钥

但是我还没有找到任何正式的文件来证明是这样的,所以我不能确定。

【问题讨论】:

  • 2 倍公钥大小和 8 倍私钥大小是好的上限。如果您真的需要更准确,那么您需要查看键中的元素以及它们是如何序列化的。可以准确计算,但有效密钥有多种形式,并非私钥的所有元素都是强制性的。这个问题可能太宽泛了,因为有许多大小不同的有效键。
  • 上限绰绰有余。我只需要一个数据库的上限。
  • @ArtjomB。另外,您是根据什么来确定这些数字的。我的密钥大小是 2048 位,那么我的上界 2048 用于私有,1024 用于公共?
  • 2048 位是 256 字节。因为我们在这里讨论 ASCII,所以一个字符就是一个字节。所以 2 * 256 chars = 512 chars 是公钥的上限,而 8 * 256 chars = 2048 chars 是私钥的上限。当然,如果您允许使用非标准的公共指数,则这两个因子都必须加一。
  • 哎呀出现了轻微的计算错误。另外,您从哪里计算出上界以及“如果您允许非标准公共指数,则这两个因子必须加一”是什么意思?

标签: database openssl rsa varchar


【解决方案1】:

RSA 私钥和公钥的最大长度是多少?

理论上没有限制。在实践中,有一个限制。此外,通常限制模数大小 (n = p*q),而不是 本身 的公钥或私钥。您可能会面临来自 Web 服务器或数据库的额外限制。

对于 OpenSSL 和 RSA,您的 RSA 密钥在生成时限制为 16K。在密钥交换期间使用的 OpenSSL 的 s_client 实用程序也施加了限制。密钥交换期间的限制是 2K,对我来说似乎是人为的低。您可以通过避免在密钥协商期间使用密钥传输方案(即使用 DH 或 EDH 而不是 RSA)来避开s_client 的限制。

如果您开始达到极限,则通常表明是时候切换到椭圆曲线了。 16K RSA 和 521 位 EC 提供大约 512 位的安全性。

另请参阅 OpenSSL 用户邮件列表中的 Openssl software failure for RSA 16K modulus


以下是使用Crypto++ library 从小(256 位)到大(60K 位)生成 RSA 密钥的一些事实。我相信这些数字是大约 5 年前在 Core2 Duo 机器上收集的。 OpenSSL 应该具有渐近相似的运行时间。

cryptopp$ rsa_kgen.exe 61440
Elapsed time for 61140 RSA key: 25654.01s (7 hours, 7 minutes, 34 seconds)
cryptopp$ rsa_kgen.exe 30720
Elapsed time for 30720 RSA key: 2255.30s (37 minutes, 35 seconds)
cryptopp$ rsa_kgen.exe 15360
Elapsed time for 15360 RSA key: 285.05s (4 minutes, 45 seconds)
cryptopp$ rsa_kgen.exe 11776
Elapsed time for 11776 RSA key: 142.52s (2 minutes, 22 seconds)
cryptopp$ rsa_kgen.exe 8192
Elapsed time for 8192 RSA key: 43.08s (43 seconds)
cryptopp$ rsa_kgen.exe 4096
Elapsed time for 4096 RSA key: 0.70s
cryptopp$ rsa_kgen.exe 2048
Elapsed time for 2048 RSA key: 0.09s
cryptopp$ rsa_kgen.exe 1024
Elapsed time for 1024 RSA key: 0.01s
cryptopp$ rsa_kgen.exe 512
Elapsed time for 512 RSA key: 0.00s
cryptopp$ rsa_kgen.exe 256
Elapsed time for 256 RSA key: 0.00s

【讨论】:

  • 哇,答案很详细。那么在您看来,我的数据库中什么是好的上限,因为我显然需要一个上限。
  • @YahyaUddin - 您使用具有安全级别的密钥来满足您的需求。如果数据库因为太大而无法存储它,那么您可以增加字段大小或切换数据库以确保满足您的安全要求。另见Are there any limits on length of string in mysql?String field length in Postgres SQL?How SQLite on Android handles long strings? 也许您应该提供数据库引擎的名称和您的架构。
  • 我正在使用 MySql。我想定义字符串长度的上限。
  • @YahyaUddin - 只是猜测(可能会浪费一些空间),但使用 3*sizeof(n)*EncodingFactor+3*80 作为公钥,并使用 9*sizeof(n)*EncodingFactor+3*80为私钥。 c*sizeof(n) 用于公钥的两个字段或私钥的八个字段。 EncodingFactor 尝试补偿 ASN.1 -> ASCII 编码扩展(如 Hex、Base32 或 Base64)。 3*80 尝试考虑封装前和封装后的标头。对于 DEK-Info 等字段,您可能需要将其发送至 5*80
  • 在我的情况下,nencodingFactor 是什么。我知道我的密钥大小是 2048。我只需要知道我需要在 MySQL 中指定多少个字符。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-07
  • 2012-01-28
  • 1970-01-01
  • 2010-11-16
相关资源
最近更新 更多