在充气城堡中生成ECDSA私钥会返回PUBLIC密钥 [英] Generating a ECDSA Private key in bouncy castle returns a PUBLIC key
问题描述
我正在尝试使用充气城堡来生成ECDSA密钥。代码似乎从Java的角度来看很好;但是,当我转储文件并尝试验证数据时,OpenSSL不喜欢数据的格式。
I am attempting to use bouncy castle to generate ECDSA keys. The code seems to work fine from the Java perspective; but, when I dump the file and try to validate the data, OpenSSL does not like the format of the data.
经过一番研究,我认为充气城堡正在编码私钥作为公钥。
After some research, I figured that bouncy castle is encoding the private key as public key.
这是我的Java代码:
Here is my Java code:
public class Test {
public static void main(String[] args) {
Security.addProvider(new BouncyCastleProvider());
System.out.println("Starting...");
String name = "prime256v1";
try {
KeyPairGenerator kpg = KeyPairGenerator.getInstance("ECDSA", BouncyCastleProvider.PROVIDER_NAME);
kpg.initialize(new ECGenParameterSpec(name));
KeyPair keyPair = kpg.generateKeyPair();
FileOutputStream writer = new FileOutputStream("private.key");
writer.write(keyPair.getPrivate().getEncoded());
writer.close();
} catch(Exception e) {
e.printStackTrace();
}
}
}
文件 private.key
以有效的DER格式生成;但是,当我运行以下命令来查看密钥的ASN.1结构时:
The file private.key
is generated in valid DER format; however, when I run the following command to see the ASN.1 structure of the key:
$ openssl asn1parse -inform DER -in /my/path/private.key
0:d=0 hl=3 l= 147 cons: SEQUENCE
3:d=1 hl=2 l= 1 prim: INTEGER :00
6:d=1 hl=2 l= 19 cons: SEQUENCE
8:d=2 hl=2 l= 7 prim: OBJECT :id-ecPublicKey
17:d=2 hl=2 l= 8 prim: OBJECT :prime256v1
27:d=1 hl=2 l= 121 prim: OCTET STRING [HEX DUMP]: <hex data>
为了进行比较,如果我运行以下命令使用OpenSSL生成ECDSA密钥,我会得到以下内容ASN.1结构:
For comparison, if I run the following commands to generate a ECDSA key using OpenSSL, I get the following ASN.1 structure:
$ openssl ecparam -name prime256v1 -genkey -noout -outform DER -out private.key
$ openssl asn1parse -inform DER -in private.key
0:d=0 hl=2 l= 119 cons: SEQUENCE
2:d=1 hl=2 l= 1 prim: INTEGER :01
5:d=1 hl=2 l= 32 prim: OCTET STRING [HEX DUMP]: <hex data>
39:d=1 hl=2 l= 10 cons: cont [ 0 ]
41:d=2 hl=2 l= 8 prim: OBJECT :prime256v1
51:d=1 hl=2 l= 68 cons: cont [ 1 ]
53:d=2 hl=2 l= 66 prim: BIT STRING
所以,我猜我的问题是
- 我有什么遗漏的吗?
- 或者这是一个已知的错误?
- 无论如何都可以绕过它?
推荐答案
Java以编码格式输出密钥。您应该尝试:
Java outputs key in the encoded format. You should try:
private String getPrivateKeyAsHex(PrivateKey privateKey) {
ECPrivateKey ecPrivateKey = (ECPrivateKey) privateKey;
byte[] privateKeyBytes = new byte[PRIVATE_KEY_LENGTH];
writeToStream(privateKeyBytes, 0, ecPrivateKey.getS(), PRIVATE_KEY_LENGTH);
String hex = Hex.toHexString(privateKeyBytes);
logger.debug("Private key bytes: " + Arrays.toString(privateKeyBytes));
logger.debug("Private key hex: " + hex);
return hex;
}
private String getPublicKeyAsHex(PublicKey publicKey) {
ECPublicKey ecPublicKey = (ECPublicKey) publicKey;
ECPoint ecPoint = ecPublicKey.getW();
byte[] publicKeyBytes = new byte[PUBLIC_KEY_LENGTH];
writeToStream(publicKeyBytes, 0, ecPoint.getAffineX(), PRIVATE_KEY_LENGTH);
writeToStream(publicKeyBytes, PRIVATE_KEY_LENGTH, ecPoint.getAffineY(), PRIVATE_KEY_LENGTH);
String hex = Hex.toHexString(publicKeyBytes);
logger.debug("Public key bytes: " + Arrays.toString(publicKeyBytes));
logger.debug("Public key hex: " + hex);
return hex;
}
private void writeToStream(byte[] stream, int start, BigInteger value, int size) {
byte[] data = value.toByteArray();
int length = Math.min(size, data.length);
int writeStart = start + size - length;
int readStart = data.length - length;
System.arraycopy(data, readStart, stream, writeStart, length);
}
这篇关于在充气城堡中生成ECDSA私钥会返回PUBLIC密钥的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!