java - 如何在java中生成与openssl生成的相同类型的ecdsa密钥对?

Posted

技术标签:

【中文标题】java - 如何在java中生成与openssl生成的相同类型的ecdsa密钥对?【英文标题】:How to generate same type of ecdsa keypair in java as generated by openssl? 【发布时间】:2016-05-20 10:20:03 【问题描述】:

我正在执行以下命令以在我的机器上生成 ecdsa 密钥对: openssl ecparam -genkey -name secp256k1 -noout -outform DER -out private.key 并在执行下一个命令 openssl ec -inform DER -in private.key -noout -text 时,我得到以下输出:

read EC key
Private-Key: (256 bit)
priv:
    //private key
pub: 
    04:64:0a:f7:e6:e1:a9:7f:d3:b2:ec:ad:f1:41:96:
    ee:c1:c2:e7:02:4a:54:42:ab:e8:da:9f:88:e1:02:
    46:aa:32:91:38:b5:9e:37:fc:96:d9:36:02:07:de:
    74:59:c4:a8:e0:2b:21:3a:d4:70:7d:5e:92:54:22:
    65:80:0f:df:fd
ASN1 OID: secp256k1

现在我感兴趣的是上面没有冒号的公钥,即04640af7e6e1a97fd3b2ecadf14196eec1c2e7024a5442abe8da9f88e10246aa329138b59e37fc96d9360207de7459c4a8e02b213ad4707d5e92542265800fdffd。我需要将此公钥发送到一个验证密钥是否有效的api调用。 openssl 生成的密钥在与 api 调用一起发送时被服务器接受为有效的。

但是通过 api 调用发送时在 java 中生成的公共 ecdsa 密钥被拒绝。我正在使用以下代码生成密钥对

public KeyPair getECDSAKeyPair() throws NoSuchProviderException, NoSuchAlgorithmException,
        InvalidAlgorithmParameterException 
    KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("ECDSA", "SC");
    ECGenParameterSpec spec = new ECGenParameterSpec("secp256k1");
    keyPairGenerator.initialize(spec, new SecureRandom());
    return keyPairGenerator.generateKeyPair();


public String getHexPublicKeyString(KeyPair keypair) 
    PublicKey publicKey =  keypair.getPublic();
    return Hex.toHexString(publicKey.getEncoded());

我的问题是如何生成与 OpenSSL 生成的相同类型的 ECDSA 密钥对? OpenSSL生成的密钥和java生成的代码有什么区别,OpenSSL生成的密钥被接受而java生成的密钥被拒绝?

【问题讨论】:

“我感兴趣的是上面没有冒号的公钥......” - 通过trsed 删除冒号和白色空间。另请参阅 OpenSSL wiki 上的 Elliptic Curve Cryptography。 我的意思是如何在java中创建相同类型的密钥?? 也许这会有所帮助:How can I get a PublicKey object from EC public key bytes?。问题是,您拥有来自 Java 和 OpenSSL 的 EC 密钥。您似乎对演示详细信息有疑问,但您没有告诉我们您需要什么格式。 openssl ec -inform DER -in private.key -noout -text 创建了另一种演示格式。为什么不告诉我们 API 需要什么格式?它将是 (1) PEM 或 (2) DER(可选编码,如 hex 或 Websafe Base64);和 (3) publicKey 或 (4) subjectPublicKeyInfo。 @jww 我需要我正在尝试显式转换的 DER 输出(十六进制格式)。由于这不起作用,我可以通过海绵城堡强制上述输出吗? 【参考方案1】:

我能够使用 SpongyCastle 通过以下方法生成所需的公众:

public static String getHexEncodedPublicKey(PublicKey publicKey) throws IOException, InvalidKeyException 
    ECPublicKeyParameters ecPublicKeyParameters
            = (ECPublicKeyParameters) ECUtil.generatePublicKeyParameter(publicKey);
    byte[] encoded = ecPublicKeyParameters.getQ().getEncoded(false);
    return Hex.toHexString(encoded);

【讨论】:

以上是关于java - 如何在java中生成与openssl生成的相同类型的ecdsa密钥对?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Java 中生成与 Python 示例等效的 HMAC?

如何在 Java(Android)中生成与 .Net 中相同的 AES 密钥?

有没有办法在java中生成与字母组合的ID?

为啥我使用 OpenSSL 和 Java 生成的 RSA-SHA256 签名不同?

在 Java 中生成 X509Certificate 的主题哈希

如何在 Openssl 中生成十六进制输出?