[英]Java 11 - elliptic curve private key - java.security.InvalidKeyException: IOException : DER input, Integer tag error
Small question regarding how to use an elliptic curve private key with java 11 please.关于如何在 java 11 中使用椭圆曲线私钥的小问题。
I have a those commands:我有这些命令:
openssl pkcs12 -in file.p12 -out output.txt
Enter Import Password:
MAC verified OK
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
then, I can run cat on the output:然后,我可以在 output 上运行 cat:
cat output.txt
Bag Attributes
friendlyName:
localKeyID:
Key Attributes: <No Attributes>
-----BEGIN ENCRYPTED PRIVATE KEY-----
MI[...]0=
-----END ENCRYPTED PRIVATE KEY-----
Bag Attributes
friendlyName:
localKeyID:
subject=/CN=
issuer=/CN=
-----BEGIN CERTIFICATE-----
MII[...]Z
-----END CERTIFICATE-----
Note, I use [...] to redact the actual content.请注意,我使用 [...] 来编辑实际内容。
And I just want to use this private key, the one in the -----BEGIN ENCRYPTED PRIVATE KEY----- -----END ENCRYPTED PRIVATE KEY-----
block我只想使用这个私钥,在
-----BEGIN ENCRYPTED PRIVATE KEY----- -----END ENCRYPTED PRIVATE KEY-----
块中的那个
Therefore, I tried the following: I first removed the BEGIN ENCRYPTED PRIVATE, the line breaks, the END ENCRYPTED PRIVATE KEY因此,我尝试了以下操作:我首先删除了 BEGIN ENCRYPTED PRIVATE、换行符、END ENCRYPTED PRIVATE KEY
String privateKeyPEM = "MI[...]0="; //the same private key as above
byte[] keyData = Base64.getDecoder().decode(privateKeyPEM);
EncodedKeySpec privKeySpec = new PKCS8EncodedKeySpec(keyData);
KeyFactory kf = KeyFactory.getInstance("EC");
PrivateKey privKey = kf.generatePrivate(privKeySpec);
However, I am getting this error:但是,我收到此错误:
aused by: java.security.InvalidKeyException: IOException : DER input, Integer tag error
at java.base/sun.security.pkcs.PKCS8Key.decode(PKCS8Key.java:350)
at java.base/sun.security.pkcs.PKCS8Key.decode(PKCS8Key.java:355)
at jdk.crypto.ec/sun.security.ec.ECPrivateKeyImpl.<init>(ECPrivateKeyImpl.java:74)
at jdk.crypto.ec/sun.security.ec.ECKeyFactory.implGeneratePrivate(ECKeyFactory.java:237)
at jdk.crypto.ec/sun.security.ec.ECKeyFactory.engineGeneratePrivate(ECKeyFactory.java:165)
May I ask what is the issue please?请问有什么问题吗? Also, may I ask how to fix it?
另外,请问怎么解决?
Thank you谢谢
There is no issue, but the (EC) key you try to read is an encrypted one - pure Java is not able to read this kind of keys.没有问题,但是您尝试读取的(EC)密钥是加密的 - 纯 Java 无法读取此类密钥。
You could write a lot of code to parse and decrypt the key or you use Bouncy Castle to do the job for you.您可以编写大量代码来解析和解密密钥,或者使用 Bouncy Castle 为您完成这项工作。
Add this line to the top of your program:将此行添加到程序的顶部:
Security.addProvider(new BouncyCastleProvider());
then use this function, where String s takes the encrypted key including the "-- Begin -- / end strings:然后使用这个 function,其中 String s 采用包括“--开始--/结束字符串”的加密密钥:
static public PrivateKey stringToPrivateKey(String s, String password)
throws IOException, PKCSException {
PrivateKeyInfo pki;
try (PEMParser pemParser = new PEMParser(new StringReader(s))) {
Object o = pemParser.readObject();
if (o instanceof PKCS8EncryptedPrivateKeyInfo) { // encrypted private key in pkcs8-format
System.out.println("key in pkcs8 encoding");
PKCS8EncryptedPrivateKeyInfo epki = (PKCS8EncryptedPrivateKeyInfo) o;
System.out.println("epki:" + epki.getEncryptionAlgorithm().getAlgorithm());
JcePKCSPBEInputDecryptorProviderBuilder builder =
new JcePKCSPBEInputDecryptorProviderBuilder().setProvider("BC");
InputDecryptorProvider idp = builder.build(password.toCharArray());
pki = epki.decryptPrivateKeyInfo(idp);
} else if (o instanceof PEMEncryptedKeyPair) { // encrypted private key in pkcs8-format
System.out.println("key in pkcs1 encoding");
PEMEncryptedKeyPair epki = (PEMEncryptedKeyPair) o;
PEMKeyPair pkp = epki.decryptKeyPair(new BcPEMDecryptorProvider(password.toCharArray()));
pki = pkp.getPrivateKeyInfo();
} else if (o instanceof PEMKeyPair) { // unencrypted private key
System.out.println("key unencrypted");
PEMKeyPair pkp = (PEMKeyPair) o;
pki = pkp.getPrivateKeyInfo();
} else {
throw new PKCSException("Invalid encrypted private key class: " + o.getClass().getName());
}
JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC");
return converter.getPrivateKey(pki);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.