从 PKCS8 编码数据创建任何 PrivateKey 实例(RSA 或 DSA 或 EC)

Med*_*One 6 java rsa pkcs#8 ecdsa java-security

我有一个代表私钥的未加密 PKCS8 编码文件。它可以是这些私钥类型中的任何一种 - RSA、DSA 或 EC。我在 ASN1 解码器 ( https://lapo.it/asn1js/ ) 中查看了这些文件,我可以看到数据中的类型(RSA、DSA 或 EC)。

有没有办法将 PKC8 私钥数据读入正确的私钥 Java 对象,而无需在这样的代码中指定密钥类型 -

PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(pkcs8key);
KeyFactory factory = KeyFactory.getInstance("RSA"); // Avoid "RSA" here?
PrivateKey privateKey = factory.generatePrivate(spec);
Run Code Online (Sandbox Code Playgroud)

有没有办法避免在 中指定算法KeyFactory.getInstance("RSA")?这不应该由 确定,PKCS8EncodedKeySpec因为它在 PKCS8 数据中可用?

示例未加密的 PKCS8 数据及其显示密钥类型的 ASN1 解码 -

动态搜索广告 -链接

EC -链接

RSA -链接

Med*_*One 5

这可以在 BouncyCastle API 的帮助下实现 -

/** Read a PKCS#8 format private key. */
private static PrivateKey readPrivateKey(InputStream input)
throws IOException, GeneralSecurityException {
    try {
        byte[] buffer = new byte[4096];
        int size = input.read(buffer);
        byte[] bytes = Arrays.copyOf(buffer, size);
        /* Check to see if this is in an EncryptedPrivateKeyInfo structure. */
        PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(bytes);
        /*
         * Now it's in a PKCS#8 PrivateKeyInfo structure. Read its Algorithm
         * OID and use that to construct a KeyFactory.
         */
        ASN1InputStream bIn = new ASN1InputStream(new ByteArrayInputStream(spec.getEncoded()));
        PrivateKeyInfo pki = PrivateKeyInfo.getInstance(bIn.readObject());
        String algOid = pki.getPrivateKeyAlgorithm().getAlgorithm().getId();
        return KeyFactory.getInstance(algOid).generatePrivate(spec);
    } finally {
        input.close();
    }
}
Run Code Online (Sandbox Code Playgroud)