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

标签 java rsa ecdsa java-security pkcs#8

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

有没有办法将 PKC8 私钥数据读取到正确的私钥 Java 对象中,而无需在代码中指定 key 类型,如下 -

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

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

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

DSA - link

EC - link

RSA - link

最佳答案

这可以借助 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();
    }
}

关于java - 从 PKCS8 编码数据创建任何 PrivateKey 实例(RSA 或 DSA 或 EC),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51951185/

相关文章:

cryptography - RSA加密问题[有效负载数据大小]

algorithm - 16、32 或 64 位处理器执行多少个原始操作来执行 N 位二进制数的逻辑右移?

smartcard - 获取JavaCard中CryptoException的原因

java - 将数组 [] 从 AsyncTask 返回到 Main Activity

java - 用于添加多个对象实例的可变参数

php - 如何使用公共(public) RSA key 验证 JSON Web token ?

php - 如何在 Codeigniter RSA 库中生成签名和 key

使用带有 SHA256 证书的 ECDSA 进行 C# 签名验证

java - 为什么我的 "Save"按钮不起作用?

java - FC 尝试启动我的 Android AccessibilityService