将椭圆曲线私钥转换为(未加密的)PKCS#8 格式
Convert elliptic curve private key to (unencrypted) PKCS#8 format
我正在尝试转换 EC 私钥
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIE2tzb8O0gBVw2IFOB/B8l1Ztjax3ut4DeNtuC3UMmZ6oAoGCCqGSM49
AwEHoUQDQgAEayT6Tv8zZlpIUOKHEYnmsKZyTaqOHajL0InS4c5tK4fhkHZDSWUa
3tPl1ibIXt0LvaxHk47h0Tc4SGr3Ex8Bhg==
-----END EC PRIVATE KEY-----
私钥
-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgTa3Nvw7SAFXDYgU4
H8HyXVm2NrHe63gN4224LdQyZnqhRANCAARrJPpO/zNmWkhQ4ocRieawpnJNqo4d
qMvQidLhzm0rh+GQdkNJZRre0+XWJshe3Qu9rEeTjuHRNzhIavcTHwGG
-----END PRIVATE KEY-----
像这样执行openSsl命令就非常简单了:
openssl pkcs8 -topk8 -nocrypt -in ec1.pem -out ec2.pem
但我想以 Java 的方式执行此操作,但没有找到任何解决方案(从 Whosebug 尝试了很多)。
所以我现在关注 class:
ECNamedCurveParameterSpec ecNamedCurveParameterSpec = ECNamedCurveTable.getParameterSpec("prime256v1");
KeyPairGenerator keyPair = KeyPairGenerator.getInstance("ECDSA", "BC");
// Create a secure random number generator using the SHA1PRNG algorithm
SecureRandom secureRandomGenerator = SecureRandom.getInstance("SHA1PRNG");
keyPair.initialize(ecNamedCurveParameterSpec, secureRandomGenerator);
然后我生成KeyPair并在ECPrivateKey对象中获取PrivateKey:
KeyPair pair =keyPair.generateKeyPair();
ECPrivateKey privateKey = (ECPrivateKey) pair.getPrivate();
StringWriter sw = new StringWriter();
try (JcaPEMWriter jcaPEMWriter = new JcaPEMWriter(sw);) {
jcaPEMWriter.writeObject(privateKey);
}
String pemFormat = sw.toString();
这个字符串pemFormat实际上是以BEGIN EC PRIVATE KEY
开头的PEM格式
我怎样才能将它转换为 BEGIN PRIVATE KEY
?
我认为如果 openSsl 可以做到,那应该是一种方式。
根本不需要从 SEC1/PEM (-----BEGIN EC PRIVATE KEY-----...
) 到 PKCS#8/PEM 格式 (-----BEGIN PRIVATE KEY-----...
) 的转换,因为 privateKey.getEncoded()
returns the key already in PKCS#8 format. So it only needs to be exported as PEM e.g. with a PemWriter
:
import org.bouncycastle.util.io.pem.PemWriter;
...
// Your code
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
...
ECPrivateKey privateKey = (ECPrivateKey)pair.getPrivate();
System.out.println(privateKey.getFormat()); // PKCS#8
// Export as PKCS#8 PEM encoded key via PemWriter
StringWriter stringWriter = new StringWriter();
try (PemWriter pemWriter = new PemWriter(stringWriter)){
pemWriter.writeObject((PemObjectGenerator)new PemObject("PRIVATE KEY", privateKey.getEncoded()));
}
String pkcs8PEM = stringWriter.toString();
System.out.println(pkcs8PEM); // -----BEGIN PRIVATE KEY-----MIGTAg...-----END PRIVATE KEY-----
您可以在 ASN.1 解析器中检查格式,例如https://lapo.it/asn1js.
但是,如果您真的想要将 SEC1/PEM 密钥显式转换为 PKCS#8/PEM 密钥,则描述了 SEC1/PEM 密钥的导入,例如here。然后可以使用 PemWriter
将导入的密钥导出为 PKCS#8/PEM 密钥,如上例所示。
我正在尝试转换 EC 私钥
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIE2tzb8O0gBVw2IFOB/B8l1Ztjax3ut4DeNtuC3UMmZ6oAoGCCqGSM49
AwEHoUQDQgAEayT6Tv8zZlpIUOKHEYnmsKZyTaqOHajL0InS4c5tK4fhkHZDSWUa
3tPl1ibIXt0LvaxHk47h0Tc4SGr3Ex8Bhg==
-----END EC PRIVATE KEY-----
私钥
-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgTa3Nvw7SAFXDYgU4
H8HyXVm2NrHe63gN4224LdQyZnqhRANCAARrJPpO/zNmWkhQ4ocRieawpnJNqo4d
qMvQidLhzm0rh+GQdkNJZRre0+XWJshe3Qu9rEeTjuHRNzhIavcTHwGG
-----END PRIVATE KEY-----
像这样执行openSsl命令就非常简单了:
openssl pkcs8 -topk8 -nocrypt -in ec1.pem -out ec2.pem
但我想以 Java 的方式执行此操作,但没有找到任何解决方案(从 Whosebug 尝试了很多)。 所以我现在关注 class:
ECNamedCurveParameterSpec ecNamedCurveParameterSpec = ECNamedCurveTable.getParameterSpec("prime256v1");
KeyPairGenerator keyPair = KeyPairGenerator.getInstance("ECDSA", "BC");
// Create a secure random number generator using the SHA1PRNG algorithm
SecureRandom secureRandomGenerator = SecureRandom.getInstance("SHA1PRNG");
keyPair.initialize(ecNamedCurveParameterSpec, secureRandomGenerator);
然后我生成KeyPair并在ECPrivateKey对象中获取PrivateKey:
KeyPair pair =keyPair.generateKeyPair();
ECPrivateKey privateKey = (ECPrivateKey) pair.getPrivate();
StringWriter sw = new StringWriter();
try (JcaPEMWriter jcaPEMWriter = new JcaPEMWriter(sw);) {
jcaPEMWriter.writeObject(privateKey);
}
String pemFormat = sw.toString();
这个字符串pemFormat实际上是以BEGIN EC PRIVATE KEY
我怎样才能将它转换为 BEGIN PRIVATE KEY
?
我认为如果 openSsl 可以做到,那应该是一种方式。
根本不需要从 SEC1/PEM (-----BEGIN EC PRIVATE KEY-----...
) 到 PKCS#8/PEM 格式 (-----BEGIN PRIVATE KEY-----...
) 的转换,因为 privateKey.getEncoded()
returns the key already in PKCS#8 format. So it only needs to be exported as PEM e.g. with a PemWriter
:
import org.bouncycastle.util.io.pem.PemWriter;
...
// Your code
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
...
ECPrivateKey privateKey = (ECPrivateKey)pair.getPrivate();
System.out.println(privateKey.getFormat()); // PKCS#8
// Export as PKCS#8 PEM encoded key via PemWriter
StringWriter stringWriter = new StringWriter();
try (PemWriter pemWriter = new PemWriter(stringWriter)){
pemWriter.writeObject((PemObjectGenerator)new PemObject("PRIVATE KEY", privateKey.getEncoded()));
}
String pkcs8PEM = stringWriter.toString();
System.out.println(pkcs8PEM); // -----BEGIN PRIVATE KEY-----MIGTAg...-----END PRIVATE KEY-----
您可以在 ASN.1 解析器中检查格式,例如https://lapo.it/asn1js.
但是,如果您真的想要将 SEC1/PEM 密钥显式转换为 PKCS#8/PEM 密钥,则描述了 SEC1/PEM 密钥的导入,例如here。然后可以使用 PemWriter
将导入的密钥导出为 PKCS#8/PEM 密钥,如上例所示。