java :RSA 加密中 public 密钥的常见模式
java : Common pattern in public keys in RSA encryption
我开始注意到我在 java 中生成的 public 键在打印时在开头和结尾有一个共同的重复或模式。
这些是我生成的 public 键,当我尝试以字符串格式打印时,它们是这种形式:
这是我用来生成密钥的代码:
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);
第一个 public 键:
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAluBZlkmIH0GCt3z8B/y7PFECBKdlkRHZeGA/OOBOM/RNvBU+kyccN1TcDxeA/YmoOWUy8JuOj14Iv600mdmWAPUkm56w780o+7Ev8V9c6FLtyCcBI0bVknJTdGopaZRa1GgU11tivmBcPp6qpRodtVoBjBuWYatSDXyuso20yNGSm4muSsysFRsbpm236lmjk7T2nM8Rlv4LmjMlm63dhLJxCK2lB8guf7pCZFx/OPe32lXTBADx0Ci/DJfrgA1KhKVtzOttnS5/TfOLHIkfJ5CZj/oThQ/zfkc4Y5Qz/7XFz/KV9xeyZdKDVBMsf/Ib11X5w9pGmwlJUbeq08RqHwIDAQAB
第二个:
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiza6s7dpiMkh1T+W8bvgpbZXJxMm0W19PaDy2z1rEkjuIxOzp1WqVbEBrBWjiaH6HhN6sN60gTYxZF5mmRNFKQjc5ElOzY4/vnvi2NrUQpJudWR8SZetU0zFIurgUca7mM8WqMBOv6Blg8A25PfJrxDekmtbnAf3DFlRxvJTfqd6d4WAhVn1WoT9ce6DkRZJ8t73IgujcRlquVg2pTFO0wqN7xFzoQ70dPww243mQTzyJlcLmEkqAJi3xSyh8vFtgEM/jY1YwqQ5yjBqC1U55CiChuoNZ6g6obHC5G8sOOmWYr4dnDp2w8hNl7LssTexMOmCCd3cyue71FcsQk0LtQIDAQAB
这些模式是什么意思?在 public 键的开头使用这些模式是否安全?它们是否构成漏洞?
正如评论中已经指出的那样:这些键是 public 键的二进制编码。 public 密钥至少包含模数和 public 指数,因此需要某种结构。对于密码学,这些组件通常使用 ASN.1 符号进行描述,并使用 BER/DER 编码进行编码。
通常,ASN.1 BER 编码对于不同的值会很快变得不同,因为它们包含长度编码。然而,RSA public 密钥并非如此,因为模数和 public 指数的大小始终相同。只有模数的值可能会发生变化,因为它对于每个密钥对都是唯一的(如果不是,则随机数生成器已损坏)。
Java 中的 public 密钥使用 X.509 证书规范中的 SubjectPublicKeyInfo
结构。优于通常的 PKCS#1 编码的优点是它包含一个对象标识符 - 在开始 - 表明它是一个 RSA public 密钥。因此可以检查此对象标识符以确保它确实是 RSA public 密钥。
要快速查看结构,请在解码 base 64 后使用 openssl -inform DER
。您也可以使用一些在线工具,例如 this one 查看 public 的内容关键结构。当然,只使用 public 和在线工具测试密钥。
通常,值 30 8x
是任何具有显着大小的 ASN.1 结构的开始。值30
是一个SEQUENCE,多元素结构通常需要它,8
是长度编码的开始。因此,以 MI
开头的 base 64 中的任何内容都可能在 ASN.1 BER/DER 中编码,因为 MI
编码前 12 位。
我开始注意到我在 java 中生成的 public 键在打印时在开头和结尾有一个共同的重复或模式。
这些是我生成的 public 键,当我尝试以字符串格式打印时,它们是这种形式:
这是我用来生成密钥的代码:
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);
第一个 public 键:
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAluBZlkmIH0GCt3z8B/y7PFECBKdlkRHZeGA/OOBOM/RNvBU+kyccN1TcDxeA/YmoOWUy8JuOj14Iv600mdmWAPUkm56w780o+7Ev8V9c6FLtyCcBI0bVknJTdGopaZRa1GgU11tivmBcPp6qpRodtVoBjBuWYatSDXyuso20yNGSm4muSsysFRsbpm236lmjk7T2nM8Rlv4LmjMlm63dhLJxCK2lB8guf7pCZFx/OPe32lXTBADx0Ci/DJfrgA1KhKVtzOttnS5/TfOLHIkfJ5CZj/oThQ/zfkc4Y5Qz/7XFz/KV9xeyZdKDVBMsf/Ib11X5w9pGmwlJUbeq08RqHwIDAQAB
第二个:
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiza6s7dpiMkh1T+W8bvgpbZXJxMm0W19PaDy2z1rEkjuIxOzp1WqVbEBrBWjiaH6HhN6sN60gTYxZF5mmRNFKQjc5ElOzY4/vnvi2NrUQpJudWR8SZetU0zFIurgUca7mM8WqMBOv6Blg8A25PfJrxDekmtbnAf3DFlRxvJTfqd6d4WAhVn1WoT9ce6DkRZJ8t73IgujcRlquVg2pTFO0wqN7xFzoQ70dPww243mQTzyJlcLmEkqAJi3xSyh8vFtgEM/jY1YwqQ5yjBqC1U55CiChuoNZ6g6obHC5G8sOOmWYr4dnDp2w8hNl7LssTexMOmCCd3cyue71FcsQk0LtQIDAQAB
这些模式是什么意思?在 public 键的开头使用这些模式是否安全?它们是否构成漏洞?
正如评论中已经指出的那样:这些键是 public 键的二进制编码。 public 密钥至少包含模数和 public 指数,因此需要某种结构。对于密码学,这些组件通常使用 ASN.1 符号进行描述,并使用 BER/DER 编码进行编码。
通常,ASN.1 BER 编码对于不同的值会很快变得不同,因为它们包含长度编码。然而,RSA public 密钥并非如此,因为模数和 public 指数的大小始终相同。只有模数的值可能会发生变化,因为它对于每个密钥对都是唯一的(如果不是,则随机数生成器已损坏)。
Java 中的 public 密钥使用 X.509 证书规范中的 SubjectPublicKeyInfo
结构。优于通常的 PKCS#1 编码的优点是它包含一个对象标识符 - 在开始 - 表明它是一个 RSA public 密钥。因此可以检查此对象标识符以确保它确实是 RSA public 密钥。
要快速查看结构,请在解码 base 64 后使用 openssl -inform DER
。您也可以使用一些在线工具,例如 this one 查看 public 的内容关键结构。当然,只使用 public 和在线工具测试密钥。
通常,值 30 8x
是任何具有显着大小的 ASN.1 结构的开始。值30
是一个SEQUENCE,多元素结构通常需要它,8
是长度编码的开始。因此,以 MI
开头的 base 64 中的任何内容都可能在 ASN.1 BER/DER 中编码,因为 MI
编码前 12 位。