我正在使用 OpenSSL 和 C++ 生成 ECDSA Prime256 密钥对,并尝试使用 Java 导入十六进制版本的公钥。我将从 C++ 获得的字节数组传递给 java 中的以下函数,该函数期望字节数组采用 X.509 编码格式。
public static PublicKey getPublicKey(byte[] pk) throws NoSuchAlgorithmException, InvalidKeySpecException {
EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(pk);
KeyFactory kf = KeyFactory.getInstance(Constant.KEY_FACTORY_TYPE);
PublicKey pub = kf.generatePublic(publicKeySpec);
return pub;
}
我使用以下函数创建了一个椭圆曲线密钥对,该函数重新调整了EC_KEY*
EC_KEY* generate_keypair() {
EC_KEY *eckey = EC_KEY_new();
EC_GROUP *ecgroup = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
EC_KEY_set_group(eckey, ecgroup);
EC_KEY_set_asn1_flag(eckey, OPENSSL_EC_NAMED_CURVE);
int kpGenerationStatus = EC_KEY_generate_key(eckey);
if (kpGenerationStatus) {
return eckey;
}
return nullptr;
}
鉴于上述函数返回的密钥对,我想将公钥导出为 ASN1.DER 格式,该格式可以使用上述 java 方法导入。
我通过执行以下操作将类型EC_POINT*
为十六进制的公钥转换为:EC_POINT_point2hex()
EC_GROUP *ecgroup = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
EC_KEY *keypair = generate_keypair();
char *result = NULL;
BN_CTX *ctx;
ctx = BN_CTX_new();
const EC_POINT *pub = EC_KEY_get0_public_key(keypair);
result = EC_POINT_point2hex(ecgroup, pub, POINT_CONVERSION_UNCOMPRESSED, ctx);
printf("%s\n", result);
其中返回以下内容:
04F588CD1D7103A993D47E53D58C3F40BE8F570604CF2EA01A7657C1423EB19C51BC379F0BEE1FAA60BB9A07DE73EA9BEF7709C1C6429D4051B44F73A458FFB80D
当我使用ASN.1 解码器检查它时,我看到一条消息说Length over 48 bits not supported at position 1
并尝试使用 java 方法导入它,我收到如下错误:
java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException: DerInputStream.getLength(): Should use short form for length
将公钥从 EC_POINT* 导出到 X.509 编码的十六进制字符串时,我是否遗漏了什么,我可以导入该字符串以验证任何签名?