公钥是否可以具有与私钥不同的长度(加密)?

时间:2013-10-13 07:57:56

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

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

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

5 个答案:

答案 0 :(得分:12)

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

RSA

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

RSA私钥可以用不同的形式表示,但通常我们会存储值pqdpdqednInvQ。它们的组合大小比公钥大。其中大多数并非严格要求,但可以方便地使用它们而不是重新生成它们。给定epq的所有内容都是直接的。

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

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

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

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

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

椭圆曲线

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

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

作为种子的私钥

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

公钥指纹

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

摘要

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

答案 1 :(得分:7)

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

但是,对于某些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和任何其他利用公钥加密的系统中,您将找到与密钥大小相关的相同一致性。在每个实现中,为了具有匹配的公钥和私钥对,必须从私钥导出公钥。由于私钥是以密钥大小为常量生成的,因此该密钥大小必须由公钥继承。如果公钥没有包含私钥的所有正确共享信息,那么根据定义,它将与该密钥不匹配,因此加密/解密过程和签名/验证过程将失败。

答案 2 :(得分:0)

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

答案 3 :(得分:-2)

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

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

编辑:

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

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

答案 4 :(得分:-2)

对于RSA,您的公钥可以小到2位。这是3号可以是你的公钥。 RSA公钥的一个流行选择是17。