EC密钥对生成Java代码与JavaKeyStore Explorer应用程序
我创建了一个密钥对EC NIST p-256,具有: [ 私钥的ASN.1格式如下所示:EC密钥对生成Java代码与JavaKeyStore Explorer应用程序,java,cryptography,Java,Cryptography,我创建了一个密钥对EC NIST p-256,具有: [ 私钥的ASN.1格式如下所示: SEQUENCE { INTEGER=0 SEQUENCE { OBJECT IDENTIFIER=EcPublicKey (1.2.840.10045.2.1) OBJECT IDENTIFIER=Prime256v1 (1.2.840.10045.3.1.7) } OCTET STRING, encapsulates: SEQUENCE { INTEGE
SEQUENCE
{
INTEGER=0
SEQUENCE
{
OBJECT IDENTIFIER=EcPublicKey (1.2.840.10045.2.1)
OBJECT IDENTIFIER=Prime256v1 (1.2.840.10045.3.1.7)
}
OCTET STRING, encapsulates:
SEQUENCE
{
INTEGER=1
OCTET STRING=
A3 6E C5 71 D3 15 F1 87 ÃnÅqÓ.õ.
E9 BF AF 78 74 74 67 BC é¿ xttg¼
4D A0 69 BF 53 3A C2 E0 M i¿S:Âà
D8 F6 F5 BC 2E C1 B4 CC Øöõ¼..´Ì
TAGGED [0]:
OBJECT IDENTIFIER=Prime256v1 (1.2.840.10045.3.1.7)
TAGGED [1]:
BIT STRING=
E6 A9 E2 62 AB 3C 9E 43 ..^Ñ..)X
E6 A9 E2 62 AB 3C 9E 43 #óþ[æEYî
E6 A9 E2 62 AB 3C 9E 43 .h®Î..Ë5
E6 A9 E2 62 AB 3C 9E 43 #óþ[æEYî
E6 A9 E2 62 AB 3C 9E 43 &.^5.ù¥.
E6 A9 E2 62 AB 3C 9E 43 #óþ[æEYî
E6 A9 E2 62 AB 3C 9E 43 #óþ[æEYî
E6 A9 E2 62 AB 3C 9E 43 .Ëkut.èö
93 .
}
}
然后我试图通过代码实现同样的目标:
private static final String KEY_BEGIN_PRIVATE = "-----BEGIN PRIVATE KEY-----\n";
private static final String KEY_END_PRIVATE = "-----END PRIVATE KEY-----\n";
private static void CreateCertificate(BigInteger serialNumber) throws Exception {
//Create key
KeyPairGenerator keypairGen = KeyPairGenerator.getInstance("EC");
ECGenParameterSpec ecgenspec = new ECGenParameterSpec(curve); //curve = "NIST P-256"
keypairGen.initialize(ecgenspec);
KeyPair keypair = keypairGen.generateKeyPair()
X500Name subject = CreateSubject();
X509v3CertificateBuilder certificate = CreateCertificateBuilder(subject,
keypair.getPublic(), serialNumber);
ContentSigner signer = new JcaContentSignerBuilder("SHA256withECDSA")
.build(keypair.getPrivate());
X509CertificateHolder holder = certificate.build(signer);
JcaX509CertificateConverter converter = new JcaX509CertificateConverter();
converter.setProvider(new BouncyCastleProvider());
X509Certificate x509 = converter.getCertificate(holder);
// Encode to pem
org.apache.commons.codec.binary.Base64 encoder = new
org.apache.commons.codec.binary.Base64(64);
byte[] derKey = key.getEncoded();
String pemKey = KEY_BEGIN_PRIVATE + encoder.encodeAsString(derKey) + KEY_END_PRIVATE;
//Write to disk
writer = null;
File file = new File("somepath");
file.createNewFile();
writer = new BufferedWriter(new FileWriter(file));
writer.write(pemKey);
writer.close();
}
密钥创建工作正常,没有错误,但在ASN.1中密钥看起来不同,尽管算法相同。缺少标记的[1]部分
SEQUENCE
{
INTEGER=0
SEQUENCE
{
OBJECT IDENTIFIER=EcPublicKey (1.2.840.10045.2.1)
OBJECT IDENTIFIER=Prime256v1 (1.2.840.10045.3.1.7)
}
OCTET STRING, encapsulates:
SEQUENCE
{
INTEGER=1
OCTET STRING=
66 28 18 9F 7C 34 7A 5B f(..|4z[
23 F3 FE 5B E6 45 59 EE #óþ[æEYî
E6 A9 E2 62 AB 3C 9E 43 æ©âb«<.C
7B CC 8C 13 D1 26 3B 87 {Ì..Ñ&;.
TAGGED [0]:
OBJECT IDENTIFIER=Prime256v1 (1.2.840.10045.3.1.7)
}
}
在我看来,这与我如何创建密钥和证书有关,但告诉我我的基本编码错误的异常让我感到疑惑,因为密钥可以在导入时通过keystore explorer和openssl comand line很好地读取
我的问题是:
- 代码中是否有一些愚蠢的错误或我做错的事情
- java密钥库浏览器与我有什么不同
附加:我无法访问读取密钥和证书的应用程序的源代码,因此我无法检查实现。但由于其他密钥有效,我假设错误在我这边。密钥不会在任何生产或测试场景中使用,因此在此处发布它们是安全的,我还修改了值,但这是错误的我不会对您造成任何影响。所以我检查了我的代码并发现了错误。我只是忘记了在每个64位拆分编码字符串 我更改了密钥的编码方式,如下所示(见此处):
所以我检查了我的代码,发现了错误。我只是忘了在每个64位拆分编码字符串 我更改了密钥的编码方式,如下所示(见此处):
错误是应用程序需要base64数据,但无法获取该数据。由于您没有源代码,而且“d”是有效的base64字符,我只能猜测错误是指CR字符0x0d。请从base64数据中删除这些字符。可能会删除所有空白。可能会在
Java.util中使用Java base64编码器代码>。您删除了一个依赖项,默认情况下它不会生成空白。错误是应用程序需要base64数据,但无法获取该数据。由于您没有源代码,而且“d”是有效的base64字符,我只能猜测错误是指CR字符0x0d。请从base64数据中删除这些数据。可能会获取清除所有空白。可能在Java.util
中使用Java Base64编码器。删除一个依赖项,默认情况下它不会生成空白。
java.lang.IllegalArgumentException: Illegal base64 character d
private static String BaseEncode(byte[] data) {
String encoded = Base64.encodeBase64String(data);
String formatted="";
for (String substring : Splitter.fixedLength(64).split(encoded)) {
formatted += substring + "\n";
}
return formatted;
}