我开始注意到我在java中生成的公钥在打印时在开头和结尾都有一个共同的重复或模式。
这些是我生成的公钥,当我尝试以字符串格式打印时,它们采用以下形式:
这是我用来生成密钥的代码:
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(2048);
KeyPair kp = kpg.generateKeyPair();
PublicKey pub = kp.getPublic();
PrivateKey pvt = kp.getPrivate();
byte[] encodedPublicKey = pub.getEncoded();
String b64PublicKey = Base64.getEncoder().encodeToString(encodedPublicKey);
System.out.println(b64PublicKey);
第一个公钥:
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAluBZlkmIH0GCt3z8B/y7PFECBKdlkRHZeGA/OOBOM/RNvBU+kyccN1TcDxeA/YmoOWUy8JuOj14Iv600mdmWAPUkm56w780o+7Ev8V9c6FLtyCcBI0bVknJTdGopaZRa1GgU11tivmBcPp6qpRodtVoBjBuWYatSDXyuso20yNGSm4muSsysFRsbpm236lmjk7T2nM8Rlv4LmjMlm63dhLJxCK2lB8guf7pCZFx/OPe32lXTBADx0Ci/DJfrgA1KhKVtzOttnS5/TfOLHIkfJ5CZj/oThQ/zfkc4Y5Qz/7XFz/KV9xeyZdKDVBMsf/Ib11X5w9pGmwlJUbeq08RqHwIDAQAB
第二个:
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiza6s7dpiMkh1T+W8bvgpbZXJxMm0W19PaDy2z1rEkjuIxOzp1WqVbEBrBWjiaH6HhN6sN60gTYxZF5mmRNFKQjc5ElOzY4/vnvi2NrUQpJudWR8SZetU0zFIurgUca7mM8WqMBOv6Blg8A25PfJrxDekmtbnAf3DFlRxvJTfqd6d4WAhVn1WoT9ce6DkRZJ8t73IgujcRlquVg2pTFO0wqN7xFzoQ70dPww243mQTzyJlcLmEkqAJi3xSyh8vFtgEM/jY1YwqQ5yjBqC1U55CiChuoNZ6g6obHC5G8sOOmWYr4dnDp2w8hNl7LssTexMOmCCd3cyue71FcsQk0LtQIDAQAB
这些模式意味着什么,并且在公钥开头有这样的模式是否安全并且它们是否构成漏洞?
答案 0 :(得分:2)
正如评论中已经指出的那样:这些密钥是公钥的二进制编码。公钥至少由模数和公共指数组成,因此需要某种结构。对于加密,这些组件通常使用ASN.1表示法进行描述,并使用BER / DER编码进行编码。
通常,ASN.1 BER编码对于不同的值会很快变得不同,因为它们包含长度编码。然而,对于RSA公钥,情况并非如此,因为模数和公共指数将始终具有相同的大小。只有模数的值可能会发生变化,因为它对每个密钥对都是唯一的(如果不是那么随机数生成器就会被破坏)。
Java中的公钥使用X.509证书规范中的SubjectPublicKeyInfo
结构。优于通常的PKCS#1编码的优点是它包含对象标识符 - 在开始 - 表示它是RSA公钥。因此,可以检查此对象标识符以确保它确实是RSA公钥。
要快速查看结构,请在解码基础64后使用openssl -inform DER
。您还可以使用某些在线工具(如this one)查看公钥结构的内容。当然,只能使用公共密钥和测试密钥进行在线工具。
通常,值30 8x
是具有相当大小的任何ASN.1结构的开头。值30
是SEQUENCE,通常是多个元素结构所必需的,8
是长度编码的开始。因此,以MI
开头的base 64中的任何内容都可能在ASN.1 BER / DER中编码,因为MI
对前12位进行编码。