我有以下的上下文:
我使用openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 365 -nodes
来生成密钥和证书文件。
然后我使用openssl pkcs8 -in key.pem -out key-encrypted.pem -topk8
加密我的私钥。
该代码适用于key.pem
和cert.pem
,但在key-encrypted.pem
和cert.pem
上存在问题。
当它转到此行以生成私钥时,它显示一个错误java.security.InvalidKeyException: IOException : DerValue.getBigIntegerInternal, not expected 48
。
我加载了我的证书文件,并创建了X509Certificate对象,如下所示:
byte[] certData = Files.readAllBytes(certPath);
InputStream st = new ByteArrayInputStream(certData)
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
certificate = (X509Certificate) certFactory.generateCertificate(st);
字符串
然后,我加载我的私钥文件如下:
List<String> keys = Files.readAllLines(keyPath);
//I have removed the first and last line of the key content:
//-----BEGIN PRIVATE KEY----- and -----END PRIVATE KEY----- lines
String key = String.join("", keys);
//Parse it into PKCS8
byte[] decoded = Base64.decodeBase64(key);
KeyFactory kf = KeyFactory.getInstance("RSA");
PKCS8EncodedKeySpec ks = new PKCS8EncodedKeySpec(decoded);
//Now I use kf to generate private key
PrivateKey pk = kf.generatePrivate(ks);
//Then I use the following code to verify
Signature s = Signature.getInstance("SHA256withRSA");
s.initSign(pk);
byte[] sign = s.sign();
s.initVerify(certificate.getPublicKey());
s.verify(sign);
型
2条答案
按热度按时间qnakjoqk1#
较新的openssl-pkcs8版本默认使用PKCS#5 v2.0/PBES 2,更具体地说,使用PBKDF 2的 * aes 256 * 和 * hmacWithSHA 256 *(截至2016年的v1.1.0,s. comment)。
而另一个答案中建议的
EncryptedPrivateKeyInfo
在Java版本中支持PBES 2算法,截至19(针对19-21进行了测试)对于较旧的Java版本(如Java 8甚至Java 18),情况并非如此,并且会导致异常(这取决于Java版本,例如 IOException:ObjectIdentifier()--数据不是对象ID(tag = 48) 对于Java 8或 * NoSuch异常:PBES 2 SecretKeyFactory不可用 * 对于Java 18)。对于
EncryptedPrivateKeyInfo
不支持PBES 2算法的Java版本,org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo
是一个选项,它也支持PBES 2算法:字符串
nc1teljy2#
PKCS8EncodedKeySpec
只支持 inner PKCS#8结构。该类不直接支持加密的PKCS#8。但是,有EncryptedPrivateKeyInfo支持。你可以找到更多关于如何使用这个类的信息here。注意,现在它应该使用PBES2(即PBKDF2 +加密)来进行密钥推导,所以这应该是可以的。