【问题标题】:Can a public key have a different length (encryption) than the private key?公钥能否具有与私钥不同的长度(加密)?
【发布时间】:2013-10-21 00:03:40
【问题描述】:

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

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

【问题讨论】:

  • 我很难选择接受什么答案。 Ben 的回答是第一个,它是直接的(而且是正确的),但我需要先听到一些确认,这是 CodesInChaos 稍后在一个信息量很大的回答中提供的。我希望我可以同时选择这两个答案,因为在我看来这两个答案都有些互补。

标签: encryption cryptography bit public-key-encryption private-key


【解决方案1】:

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

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

编辑:

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

为了澄清我的观点,我只是说如果 e 保证 d 和 e 的大小会以可预测的方式显着不同,否则这可能被认为是一种廉价的技巧。但是,如上所述,我认为这样做没有多大意义。

【讨论】:

  • 不,请参阅我的回复,了解为什么不是(也不能)是这种情况。
【解决方案2】:

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

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

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

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

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

指向 RSA 非常好,但它取决于密钥交换协议,为此我们转到 Diffie-Hellman key exchangeoriginal patent,它们现在已过期。两者都有密钥交换方法和公私钥关系的例子和说明。

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

【讨论】:

  • 谢谢(等等等等谢谢stackoverflow,希望这足以让我感谢Ben的好意)
  • 没问题。如果您对答案感到满意,请随时接受。 :)
  • 恕我直言,您已经声明这是不可能的,没有显示或证明这是不可能的。我提供了生成密钥对的算法,你没有。常见的实现使用相似大小的键,这并不意味着它是不可能的。密钥生成算法使用抽象的整数数学,除了特定的计算机实现之外,根本没有提到比特。
  • Ben:你和大卫实际上是在讨论密钥大小的不同定义。这是可能的,因为“密钥大小”在 RSA 的上下文中是不明确的。大卫在谈论质数的大小,你在谈论别的东西。没有人知道 OP 在说什么。
  • 你的回答有点混乱,所以我不知道你是对还是错。至少对于 Diffie-Hellman,我们经常使用比公钥小得多的私钥。您首先修复组参数,例如使用 2048 位模数。有些人认为这些参数是公钥的一部分,有些人将它们固定为协议的一部分。然后你选择一个私钥x,它可以是一个 256 位的数字。然后您将公钥计算为Y = G^x,这是一个 2048 位数。选择私钥决定了公钥,但公钥可以更大。
【解决方案3】:

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

【讨论】:

  • 一般我们称模数的大小为“密钥大小”,而不是公共指数的大小。
  • 我同意,但很明显,在这种情况下,他并没有问他在哪里可以为公钥和私钥使用不同的模数,而是指数。
  • 这个问题含糊不清,但我不认为它是在谈论指数。
【解决方案4】:

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

RSA

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

RSA 私钥可以用不同的形式表示,但通常我们存储值 pqdpdqedn、@987654336 @。它们的组合大小大于公钥。其中大多数不是严格要求的,但是让它们可用而不是重新生成它们很方便。在给定 epq 的情况下重新生成所有这些是直截了当的。

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

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

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

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

因此,对于有限域加密,公钥远大于私钥。

椭圆曲线

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

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

私钥作为种子

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

公钥指纹

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

总结

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

【讨论】:

  • 是的,我的意思是 RSA 密钥的模数 n 的大小,它们在私钥和公钥中是否必须具有相同的大小,或者它们可以不同吗?感谢您的曝光:)
  • @Rolf 私钥的en 字段与公钥相同。它们是相同的数字,而不仅仅是相同的大小。如果您使用完整的私钥,包含我提到的所有字段并删除除en 之外的所有内容,您将获得公钥。
【解决方案5】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-06
    • 1970-01-01
    • 2018-02-27
    相关资源
    最近更新 更多