9

我有一个 1024 位的私钥,并用它来生成一个公钥。这是否自动意味着我的公钥也具有 1024 加密?或者它可以具有较小的加密大小?(512、256……)

PS:我最感兴趣和谈论的是 RSA 密钥中模数(“n”)的大小。大小通常为 1024 或 2048 位。但我很高兴看到这引发了讨论,而这一切都激发了我对密码学的兴趣。

4

5 回答 5

12

这取决于加密算法以及您所称的公钥/私钥。与磁盘或网络上的序列化相比,有时可以在 RAM 中使用不同的大小。

RSA

RSA 公钥由模数n和公共指数组成e。我们通常选择一个较小的值e(3,或 65537 是常见的)。的大小e对安全性影响不大。由于e通常少于四个字节且n超过一百个,因此总大小由模数决定。如果您真的想要,您可以将e其作为协议规范的一部分进行修复,以便仅n存储。

RSA 私钥可以用不同的形式表示,但通常我们存储值p, q, dp, dq, e, d, n, InvQ。它们的组合大小大于公钥。其中大多数不是严格要求的,但是让它们可用而不是重新生成它们很方便。重新生成所有给定的ep并且q是直截了当的。

当我们在 RSA 的上下文中谈论密钥大小时,我们总是指模数的大小,忽略所有其他元素。这是一个有用的约定,因为这是影响安全性的唯一值。的典型大小为n2048 位。

有限域加密(Diffie-Hellman、DSA 等)

私钥是两倍于安全级别大小的标量。典型值为 256 位。

公钥是一个组元素,比私钥大得多。典型值为 2048 位。

因此,对于有限域加密,公钥比私钥大得多。

椭圆曲线

私钥是两倍于安全级别大小的标量。典型值为 256 位。这部分与有限域加密相同。

公钥是一个组元素。序列化这种元素有两种形式。压缩后的形式略大于私钥(最多几位)。未压缩的形式大约是私钥大小的两倍。压缩形式的典型值为 256 位,未压缩形式的典型值为 512 位。

私钥作为种子

当您自己生成公钥/私钥对时,您始终可以将它们存储为 PRNG 的种子。这样,无论您使用哪种方案,它们都非常小,大约为 160 位。这样做的缺点是重新生成私钥的自然形式可能很昂贵。要求创建密钥对的方法保持不变。

公钥指纹

您通常只能存储一个 160 位左右大小的指纹,而不是存储完整的公钥。这样做的缺点是它增加了消息/签名的大小。

概括

对于某些算法,公钥和私钥的大小是相同的,而对于某些算法,它们是不同的,并且通常可以以一定成本(解压缩时间或消息大小)压缩它们中的一个或两个。

于 2013-10-13T12:14:03.623 回答
7

不可以。密钥对中的公钥始终与私钥大小匹配,实际上它是从私钥派生的。

但是,对于某些公钥加密实现,例如OpenPGP,创建密钥时会使用分配给不同任务的子密钥。这些子密钥的大小可以彼此不同,并且用于创建它们的主密钥。在这些情况下,公钥数据将指示主密钥和与相应私钥数据匹配的子密钥的密钥大小。

而许多其他公钥实现不使用子密钥(例如TLS),所以您只会看到单个密钥大小。同样,密钥大小将在公钥和私钥数据中显示。

您将看到的密钥大小的唯一变化是当非对称加密与对称加密结合使用时。对称加密(会话密钥)会更小,但它使用完全不同的算法(例如 AES、TWOFISH 等)并且不是公钥的一部分(OpenPGP 除外,其中可以保存对称密码首选项,因为它不利用实时连接建立对称加密通信并交换会话密钥数据)。

编辑:有关公钥和私钥数据之间关系的更多详细信息(也称为证明大卫错误)

指向 RSA 非常好,但它取决于密钥交换协议,为此我们去Diffie-Hellman 密钥交换原始专利,该专利现已过期。两者都有密钥交换方法以及公钥和私钥之间关系的示例和说明。

实现这种关系的算法,包括RSAEl-Gamal,都同时创建公钥和私钥。特别是通过创建一个私钥,然后生成公钥。公钥继承了私钥的所有特性。获得两个组件之间不匹配的详细信息的唯一方法是通过某种方式独立于私钥生成公钥。当然,问题在于它们不再是密钥对。

RSA 和 El-Gamal 的密钥生成描述解释了公钥和私钥之间的公共数据,特别是公钥的所有组件都是私钥的一部分,但私钥包含解密数据所需的额外数据和/或签名数据。在 El-Gamal 中,公共组件是 G、q、g 和 h,而私有组件是 G、q、g、h 和 x。

现在,关于算法中没有提到密钥对的位大小,是的,这是真的,但是它们的每个实际实现都将选定的密钥大小作为生成私钥时的常数之一。下面是在 GnuPG 中生成密钥的相关代码(选择所有选项后,包括选择密钥大小和指定密码):

static int
do_create( int algo, unsigned int nbits, KBNODE pub_root, KBNODE sec_root,
           DEK *dek, STRING2KEY *s2k, PKT_secret_key **sk, u32 timestamp,
       u32 expiredate, int is_subkey )
{
  int rc=0;

  if( !opt.batch )
    tty_printf(_(
"We need to generate a lot of random bytes. It is a good idea to perform\n"
"some other action (type on the keyboard, move the mouse, utilize the\n"
"disks) during the prime generation; this gives the random number\n"
"generator a better chance to gain enough entropy.\n") );

  if( algo == PUBKEY_ALGO_ELGAMAL_E )
    rc = gen_elg(algo, nbits, pub_root, sec_root, dek, s2k, sk, timestamp,
         expiredate, is_subkey);
  else if( algo == PUBKEY_ALGO_DSA )
    rc = gen_dsa(nbits, pub_root, sec_root, dek, s2k, sk, timestamp,
         expiredate, is_subkey);
  else if( algo == PUBKEY_ALGO_RSA )
    rc = gen_rsa(algo, nbits, pub_root, sec_root, dek, s2k, sk, timestamp,
         expiredate, is_subkey);
  else
    BUG();

  return rc;
}

三种算法之间的细微差别与已发布算法中提到的项目的值有关,但在每种情况下,“nbits”都是一个常数。

在 OpenSSL、OpenSSH 和任何其他使用公钥加密的系统中生成密钥的代码中,您会发现与密钥大小相关的相同一致性。在每个实现中,为了获得匹配的公钥和私钥对,公钥必须从私钥派生。由于私钥是使用密钥大小作为常数生成的,因此该密钥大小必须由公钥继承。如果公钥不包含与私钥共享的所有正确信息,则根据定义,它将与该密钥不匹配,因此加密/解密过程和签名/验证过程将失败。

于 2013-10-13T09:45:23.743 回答
1

我从各种来源查看,我的结论是用于 RSA 密钥生成的模数 (n=p*q) 对于公钥和私钥是相同的。模数决定了两者的密钥长度。

于 2015-01-20T20:54:46.940 回答
-1

据我了解,没有要求两个键的大小相同。检查以下如何生成密钥:
http ://en.wikipedia.org/wiki/RSA_algorithm#Key_generation

但是我相信,如果一个密钥(或模数因子)明显更小,它会削弱对密码分析的强度。

编辑:

这个讨论在很大程度上变得无关紧要,因为 OP 澄清他们对模数的大小最感兴趣,这对于加密和解密自然是相同的(不包括任何奇怪的未知密码系统)。

只是为了澄清我的观点,我只是说如果 e << d(或 d << e)您可以将密钥分配为不同的密钥大小。它们将由相同的算法使用相同的位大小数学(例如 256 位)生成,并且类似地加密和解密将需要相同数量的位。如果您查看(为了论证)数字 1 和 128,您可以选择如何表示它们。它们都可以是 8 位,或者 1 可以由 1-7 位的任意数量的位表示。除非您的密钥生成方法保证d 和 e 的大小以可预测的方式显着不同,否则这可能被认为是一种廉价的技巧。但是如前所述,我认为这样做没有多大意义。

于 2013-10-13T08:13:55.030 回答
-1

对于 RSA,您的公钥可以小到 2 位。那就是数字 3 可以是您的公钥。RSA 公钥的流行选择是 17。

于 2013-10-13T10:36:10.607 回答