Java 11 - 椭圆曲线私钥 - java.security.InvalidKeyException: IOException: DER 输入,整数标签错误
Java 11 - elliptic curve private key - java.security.InvalidKeyException: IOException : DER input, Integer tag error
关于如何使用带有 java 11 的椭圆曲线私钥的小问题。
我有一个命令:
openssl pkcs12 -in file.p12 -out output.txt
Enter Import Password:
MAC verified OK
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
然后,我可以 运行 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-----
注意,我使用 [...] 来编辑实际内容。
我只想使用这个私钥,-----BEGIN ENCRYPTED PRIVATE KEY----- -----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);
但是,我收到此错误:
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)
请问是什么问题?
另外,请问如何解决?
谢谢
没有问题,但您尝试读取的 (EC) 密钥是 加密的 密钥 - 纯 Java 无法读取此类密钥.
您可以编写大量代码来解析和解密密钥,或者使用 Bouncy Castle 来完成这项工作。
将此行添加到程序的顶部:
Security.addProvider(new BouncyCastleProvider());
然后使用此函数,其中 String s 取加密密钥,包括 "-- Begin -- / end strings:
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);
}
}
关于如何使用带有 java 11 的椭圆曲线私钥的小问题。
我有一个命令:
openssl pkcs12 -in file.p12 -out output.txt
Enter Import Password:
MAC verified OK
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
然后,我可以 运行 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-----
注意,我使用 [...] 来编辑实际内容。
我只想使用这个私钥,-----BEGIN ENCRYPTED PRIVATE KEY----- -----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);
但是,我收到此错误:
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)
请问是什么问题? 另外,请问如何解决?
谢谢
没有问题,但您尝试读取的 (EC) 密钥是 加密的 密钥 - 纯 Java 无法读取此类密钥.
您可以编写大量代码来解析和解密密钥,或者使用 Bouncy Castle 来完成这项工作。
将此行添加到程序的顶部:
Security.addProvider(new BouncyCastleProvider());
然后使用此函数,其中 String s 取加密密钥,包括 "-- Begin -- / end strings:
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);
}
}