我有一个代表私钥的未加密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);
有没有办法避免在
KeyFactory.getInstance("RSA")
中指定算法?因为它在PKCS8数据中可用,所以不应该从PKCS8EncodedKeySpec
确定它吗?显示密钥类型的未加密PKCS8数据及其ASN1解码示例-
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();
}
}