在参考我之前的问题here时,我想知道为什么我的代码对于特定输入失败并且适用于另一个。
代码:
import de.flexiprovider.core.FlexiCoreProvider;
import de.flexiprovider.ec.FlexiECProvider;
import de.flexiprovider.ec.parameters.CurveParams;
import de.flexiprovider.ec.parameters.CurveRegistry.BrainpoolP512r1;
import java.io.StringWriter;
import java.security.KeyPair;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Security;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import sun.misc.BASE64Encoder;
import sun.misc.BASE64Decoder;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openssl.jcajce.JcaPEMWriter;
public class TestClass {
public TestClass() {
Security.addProvider(new FlexiCoreProvider());
Security.addProvider(new FlexiECProvider());
Security.addProvider(new BouncyCastleProvider());
}
public KeyPair generateKeyPair() throws Exception {
KeyPairGenerator kpg = KeyPairGenerator.getInstance("ECIES");
CurveParams ecParams = new BrainpoolP512r1();
kpg.initialize(ecParams, new SecureRandom());
KeyPair keyPair = kpg.generateKeyPair();
return keyPair;
}
private String keyToPEMString(Object key) throws Exception {
StringWriter signedCertificatePEMDataStringWriter = new StringWriter();
JcaPEMWriter pemWriter = new JcaPEMWriter(signedCertificatePEMDataStringWriter);
pemWriter.writeObject(key);
pemWriter.close();
return signedCertificatePEMDataStringWriter.toString();
}
public String[] generateB64EncodedKeyPair() throws Exception {
String[] publicPrivateKeyPair = new String[2];
KeyPair keyPair = generateKeyPair();
publicPrivateKeyPair[0] = keyToPEMString(keyPair.getPublic());
publicPrivateKeyPair[1] = keyToPEMString(keyPair.getPrivate());
return publicPrivateKeyPair;
}
public String keyToString(Key anyKey) throws Exception {
return keyToPEMString(anyKey);
}
public Key stringToKey(String encodedKey, boolean isPrivate) throws Exception {
Key key = null;
KeyFactory keyFactory = KeyFactory.getInstance("ECIES"); //THIS POINT REFERRED
BASE64Decoder b64 = new BASE64Decoder();
//System.out.println("Stripped::");
byte[] keyBytes = null;
if (isPrivate) {
encodedKey = encodedKey.replace("-----BEGIN EC PRIVATE KEY-----\r\n", "").replace("-----END EC PRIVATE KEY-----", "");
//System.out.println(encodedKey);
keyBytes = b64.decodeBuffer(encodedKey);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
key = (PrivateKey) keyFactory.generatePrivate(keySpec);
// PEMParser pemRd = new PEMParser(new StringReader(encodedKey));
// ASN1ObjectIdentifier ecOID = (ASN1ObjectIdentifier) pemRd.readObject();
// X9ECParameters ecSpec = ECNamedCurveTable.getByOID(ecOID);
// if (ecSpec == null) {
// System.out.println("ecSpec not found for named curve");
// System.exit(0);
// }
// System.out.println(pemRd.readObject());
// PEMKeyPair pemPair = (PEMKeyPair) pemRd.readObject();
//
// KeyPair pair = new JcaPEMKeyConverter().setProvider("BC").getKeyPair(pemPair);
// key = pair.getPrivate();
} else {
encodedKey = encodedKey.replace("-----BEGIN PUBLIC KEY-----\r\n", "").replace("-----END PUBLIC KEY-----", "");
//System.out.println(encodedKey);
keyBytes = b64.decodeBuffer(encodedKey);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
key = (PublicKey) keyFactory.generatePublic(keySpec);
}
return key;
}
public static void main(String[] args) {
TestClass obj = new TestClass();
try {
KeyPair keyPair = obj.generateKeyPair();
System.out.println("*******************************************");
System.out.println(obj.keyToPEMString(keyPair.getPublic()));
System.out.println(obj.keyToPEMString(keyPair.getPrivate()));
System.out.println("*******************************************");
System.out.println(obj.stringToKey(obj.keyToPEMString(keyPair.getPublic()), false));
System.out.println();
System.out.println(obj.stringToKey(obj.keyToPEMString(keyPair.getPrivate()), true));
} catch (Exception e) {
e.printStackTrace();
}
}
}
我已成功使用 StringToKey 方法从其PEM格式转换RSA密钥。在将其用于EC密钥时,公钥的转换没有任何麻烦,但私钥不会。
我已经对私钥转换部分中的某个部分发表了评论,我刚刚提到我已尝试过该代码段,但结果不尽如人意。
我需要生成两个密钥并将它们存储到用户计算机上,以便根据需要加载它们。
我拥有的另一个选项是将它们存储在.p12文件中并通过我已成功完成的KeyStore加载它们,但我很想知道PEM转换后的Elliptical Private Keys字符串是否也可以考虑输出或编码转换如下。
以下是上述代码的输出:
*******************************************
-----BEGIN PUBLIC KEY-----
MIGbMBQGByqGSM49AgEGCSskAwMCCAEBDQOBggAERHQce1+hQ4jXBiB7VTKJ1UFR
xqtpqCb5Hh4MiElJNiovj8TFCfONRcYywBlqopCK45JctuMWAelTG0y+sjHB1E7H
2U3wzSMbU5q6qqeK2WoaN1uoeIYV3zBVtOdKtdqUy1fhubWfQUdQDumOCds6dFXD
5N+RHZkt6/hnXtPdWe4=
-----END PUBLIC KEY-----
-----BEGIN EC PRIVATE KEY-----
MEYCAQEEQQCXr25i9d8VeMSRBG5GJ3s+Sxj3UQhyTr9MBoPPhYTlo8dF/+gXUgrE
tW2mDD4MmtofIqWvXoVObW/FjW0NfY/a
-----END EC PRIVATE KEY-----
*******************************************
W =
(44741c7b5fa14388d706207b553289d54151c6ab69a826f91e1e0c884949362a2f8fc4c509f38d45c632c0196aa2908ae3925cb6e31601e9531b4cbeb231c1d4,
4ec7d94df0cd231b539abaaaa78ad96a1a375ba8788615df3055b4e74ab5da94cb57e1b9b59f4147500ee98e09db3a7455c3e4df911d992debf8675ed3dd59ee)
de.flexiprovider.ec.parameters.CurveRegistry$BrainpoolP512r1@e9ef02e5
de.flexiprovider.api.exceptions.InvalidKeySpecException: codec.asn1.ASN1Exception: ASN.1 type mismatch!
Expected: codec.x509.AlgorithmIdentifier
In : codec.pkcs8.PrivateKeyInfo
At index: 1
Got tag : 4 and class: 0
at de.flexiprovider.ec.keys.ECKeyFactory.generatePrivate(ECKeyFactory.java:125)
at de.flexiprovider.api.keys.KeyFactory.engineGeneratePrivate(KeyFactory.java:61)
at java.security.KeyFactory.generatePrivate(KeyFactory.java:342)
at TestClass.stringToKey(TestClass.java:70)
at TestClass.main(TestClass.java:110)
或者,我对StringToKey方法的KeyFactory行中的内联注释有疑问。我尝试过选择不同的实例,例如: “EC”
“EC”, “BC”
“EC”, “FlexiEC”
“ECDSA”
“ECDSA”, “BC”
“ECDSA”, “FlexiEC”
可悲的是,无有效。
如何才能成功将我的EC私钥的PEM转换为私钥? 要么 如何创建可以轻松转换为其原始格式的EC私钥的PEM?