没有。密钥对中的公钥始终与私钥大小匹配,实际上它是从私钥派生的。
但是,对于某些public key 加密实现,例如OpenPGP,创建密钥时会使用分配给不同任务的子密钥。这些子密钥的大小可以彼此不同,并且用于创建它们的主密钥。在这些情况下,公钥数据将指示主密钥和与相应私钥数据匹配的子密钥的密钥大小。
而许多其他公钥实现不使用子密钥(例如TLS),因此您只会看到单个密钥大小。同样,密钥大小将在公钥和私钥数据中显示。
您将看到的唯一密钥大小变化是非对称加密与对称加密结合使用时。对称加密(会话密钥)会更小,但它使用完全不同的算法(例如 AES、TWOFISH 等)并且不是公钥的一部分(OpenPGP 除外,其中对称密码首选项可以保存,因为它不利用实时连接建立对称加密通信并交换会话密钥数据)。
编辑:关于公钥和私钥数据之间关系的更多细节(也称为证明大卫错误)
指向 RSA 非常好,但它取决于密钥交换协议,为此我们转到 Diffie-Hellman key exchange 和 original patent,它们现在已过期。两者都有密钥交换方法和公私钥关系的例子和说明。
实现这种关系的算法,包括RSA 和El-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 和任何其他使用公钥加密的系统中生成密钥的代码中,您会发现与密钥大小相关的相同一致性。在每个实现中,为了获得匹配的公钥和私钥对,公钥必须从私钥派生。由于私钥是使用密钥大小作为常数生成的,因此该密钥大小必须由公钥继承。如果公钥不包含与私钥共享的所有正确信息,则根据定义,它将与该密钥不匹配,因此加密/解密过程和签名/验证过程将失败。