OpenSSH ecdsa 到 BCECPublicKey
OpenSSH ecdsa to BCECPublicKey
我想将 OpenSSH ecdsa public 密钥字符串(.pub
文件)转换为 BCECPublicKey
实例。
我想实现的是这段代码的反面:
BCECPublicKey publicKey = ...;
byte[] point = SubjectPublicKeyInfo.getInstance(ASN1Sequence.getInstance(publicKey.getEncoded())).getPublicKeyData().getOctets();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
DataOutputStream dataOutputStream = new DataOutputStream(byteArrayOutputStream);
dataOutputStream.writeInt("ecdsa-sha2-nistp256".getBytes().length);
dataOutputStream.write("ecdsa-sha2-nistp256".getBytes());
dataOutputStream.writeInt("nistp256".getBytes().length);
dataOutputStream.write("nistp256".getBytes());
dataOutputStream.writeInt(point.length);
dataOutputStream.write(point);
String base64 = Base64.getEncoder().encodeToString(byteArrayOutputStream.toByteArray());
这是我试过的:
// Valid ecdsa-sha2-nistp256 public key string from a .pub file.
String base64 = "AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBG93uDMAjwxpPFXgLFFs7FzWZXrQRaXnBMqmHaRN/5JRzljuqYAUAkW98HvFxGKrnb2JdW3X785AxLNzVhiiw+4=";
byte[] bytes = Base64.getDecoder().decode(base64);
ECNamedCurveParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec("secp256r1");
// java.lang.IllegalArgumentException: Incorrect length for infinity encoding
ECPoint point = ecSpec.getCurve().decodePoint(bytes);
ECPublicKeySpec publicKeySpec = new ECPublicKeySpec(point, ecSpec);
KeyFactory keyFactory = KeyFactory.getInstance("ECDSA", "BC");
PublicKey pk = keyFactory.generatePublic(publicKeySpec);
但这似乎不起作用。
有没有一种简单的方法可以用充气城堡做到这一点?
你知道你通过连接六个东西创建了 blob,其中只有第六个是实际的点编码,所以你怎么能想象使用所有 blob 作为点编码是正确的?
干净而稳健的方法是将 blob 解析回其片段并提取点编码;肮脏的方法是假设 blob 如预期的那样用于 ecdsa-sha2-nistp256(并且未压缩),因此最后 65 个字节是点编码:
String base64 = "AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBG93uDMAjwxpPFXgLFFs7FzWZXrQRaXnBMqmHaRN/5JRzljuqYAUAkW98HvFxGKrnb2JdW3X785AxLNzVhiiw+4=";
byte[] bytes = Base64.getDecoder().decode(base64), temp;
if( clean ){
DataInputStream instr = new DataInputStream (new ByteArrayInputStream (bytes));
temp = new byte[instr.readInt()]; instr.read(temp);
if( !Arrays.equals(temp,"ecdsa-sha2-nistp256".getBytes())) throw new Exception ("bad key");
temp = new byte[instr.readInt()]; instr.read(temp);
if( !Arrays.equals(temp,"nistp256".getBytes())) throw new Exception ("bad key");
temp = new byte[instr.readInt()]; instr.read (temp);
}else{
temp = Arrays.copyOfRange(bytes, bytes.length-65, bytes.length);
}
ECNamedCurveParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec ("secp256r1");
org.bouncycastle.math.ec.ECPoint point = ecSpec.getCurve().decodePoint (temp);
KeyFactory keyFactory = KeyFactory.getInstance("ECDSA", "BC");
PublicKey pk = keyFactory.generatePublic(new org.bouncycastle.jce.spec.ECPublicKeySpec(point, ecSpec));
我想将 OpenSSH ecdsa public 密钥字符串(.pub
文件)转换为 BCECPublicKey
实例。
我想实现的是这段代码的反面:
BCECPublicKey publicKey = ...;
byte[] point = SubjectPublicKeyInfo.getInstance(ASN1Sequence.getInstance(publicKey.getEncoded())).getPublicKeyData().getOctets();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
DataOutputStream dataOutputStream = new DataOutputStream(byteArrayOutputStream);
dataOutputStream.writeInt("ecdsa-sha2-nistp256".getBytes().length);
dataOutputStream.write("ecdsa-sha2-nistp256".getBytes());
dataOutputStream.writeInt("nistp256".getBytes().length);
dataOutputStream.write("nistp256".getBytes());
dataOutputStream.writeInt(point.length);
dataOutputStream.write(point);
String base64 = Base64.getEncoder().encodeToString(byteArrayOutputStream.toByteArray());
这是我试过的:
// Valid ecdsa-sha2-nistp256 public key string from a .pub file.
String base64 = "AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBG93uDMAjwxpPFXgLFFs7FzWZXrQRaXnBMqmHaRN/5JRzljuqYAUAkW98HvFxGKrnb2JdW3X785AxLNzVhiiw+4=";
byte[] bytes = Base64.getDecoder().decode(base64);
ECNamedCurveParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec("secp256r1");
// java.lang.IllegalArgumentException: Incorrect length for infinity encoding
ECPoint point = ecSpec.getCurve().decodePoint(bytes);
ECPublicKeySpec publicKeySpec = new ECPublicKeySpec(point, ecSpec);
KeyFactory keyFactory = KeyFactory.getInstance("ECDSA", "BC");
PublicKey pk = keyFactory.generatePublic(publicKeySpec);
但这似乎不起作用。
有没有一种简单的方法可以用充气城堡做到这一点?
你知道你通过连接六个东西创建了 blob,其中只有第六个是实际的点编码,所以你怎么能想象使用所有 blob 作为点编码是正确的?
干净而稳健的方法是将 blob 解析回其片段并提取点编码;肮脏的方法是假设 blob 如预期的那样用于 ecdsa-sha2-nistp256(并且未压缩),因此最后 65 个字节是点编码:
String base64 = "AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBG93uDMAjwxpPFXgLFFs7FzWZXrQRaXnBMqmHaRN/5JRzljuqYAUAkW98HvFxGKrnb2JdW3X785AxLNzVhiiw+4=";
byte[] bytes = Base64.getDecoder().decode(base64), temp;
if( clean ){
DataInputStream instr = new DataInputStream (new ByteArrayInputStream (bytes));
temp = new byte[instr.readInt()]; instr.read(temp);
if( !Arrays.equals(temp,"ecdsa-sha2-nistp256".getBytes())) throw new Exception ("bad key");
temp = new byte[instr.readInt()]; instr.read(temp);
if( !Arrays.equals(temp,"nistp256".getBytes())) throw new Exception ("bad key");
temp = new byte[instr.readInt()]; instr.read (temp);
}else{
temp = Arrays.copyOfRange(bytes, bytes.length-65, bytes.length);
}
ECNamedCurveParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec ("secp256r1");
org.bouncycastle.math.ec.ECPoint point = ecSpec.getCurve().decodePoint (temp);
KeyFactory keyFactory = KeyFactory.getInstance("ECDSA", "BC");
PublicKey pk = keyFactory.generatePublic(new org.bouncycastle.jce.spec.ECPublicKeySpec(point, ecSpec));