使用ASN1.DER中的point2hex导出EC_POINT,并使用Java作为X.509重新创建

问题描述 投票:2回答:1

我正在使用带有C ++的OpenSSL生成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;
}

我使用以下函数创建一个椭圆曲线密钥对,该函数返回一个qazxsw poi

EC_KEY*

鉴于上面函数返回的密钥对,我想将公钥导出为ASN1.DER格式,可以使用上面的java方法导入。

我通过执行以下操作,使用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; } 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 decoder并尝试使用java方法导入它我收到如下错误:

Length over 48 bits not supported at position 1

将公钥从EC_POINT *导出到X.509编码的十六进制字符串时,我是否遗漏了一些我可以导入以验证任何签名的字符串?

c++ openssl x509 ecdsa asn1
1个回答
0
投票

您想要ASN1 base64值的方向不正确。

java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException: DerInputStream.getLength(): Should use short form for length 正在将内部公钥值转换为十六进制。它不是ASN1格式。

您可以从命令行生成所需内容,如下所示:

  1. 生成EC私钥:openssl ecparam -name prime256v1 -genkey -noout -out key.pem
  2. DER(ASN1)格式的额外公钥:openssl ec -in key.pem -poutout -outform der -out public.cer
  3. 转换为base64 openssl base64 -in。\ public.cer

如果您将该输出并将其粘贴到ASN.1解码器链接中,它可以正常工作。

现在将其转换为代码,您可以生成EC密钥,但您需要的步骤是:

  1. 生成ASN1格式的公钥
  2. 将其转换为base64

要生成ASN1格式的公钥,您要使用EC_POINT_point2hex方法集,然后使用i2d_EC_PUBKEY过滤器转换为base64。

所以这是一个示例问题,当我将输出复制到ASN.1解码器链接时,它工作正常。

BIO_f_base64

我无法在Java方面完成,但如果它与手动openssl生成的base64字符串一起使用,那么它将与示例应用程序一起使用。

© www.soinside.com 2019 - 2024. All rights reserved.