无法从Java中读取OpenSSL生成的ECDSA密钥:InvalidKeySpecException [英] Can't read OpenSSL-generated ECDSA key from Java: InvalidKeySpecException
问题描述
我创建了ECDSA密钥对,并使用OpenSSL导出了公钥,但无法从Java中读取公钥.
I created an ECDSA keypair and exported the public key using OpenSSL, but I'm unable to read the public key in from Java.
OpenSSL中的密钥生成:
Key generation in OpenSSL:
$ openssl ecparam -name secp256k1 -genkey -noout -outform DER | openssl ec -inform DER -pubout -outform DER > secp256k1.public.der
Clojure代码从文件中读取密钥,并以[org.bouncycastle/bcprov-jdk15on "1.56"]
作为依赖项:
Clojure code that reads a key in from file, with [org.bouncycastle/bcprov-jdk15on "1.56"]
as a dependency:
(ns adhoc.ecdsa-mismatch
(:import (java.nio.file Files Paths)
(java.security Security KeyFactory)
(java.security.spec X509EncodedKeySpec)))
(when (nil? (Security/getProvider "BC"))
(Security/addProvider (org.bouncycastle.jce.provider.BouncyCastleProvider.)))
(defn read-bytes
"Read file from path as byte array."
[^String path]
(Files/readAllBytes (Paths/get path (into-array String []))))
(defn read-pubkey
[^String path]
(.generatePublic (KeyFactory/getInstance "ECDSA" "BC")
(X509EncodedKeySpec. (read-bytes path))))
(require '[adhoc.ecdsa-mismatch :as mm])
(mm/read-pubkey "secp256k1.public.der")
;; InvalidKeySpecException java.lang.NullPointerException org.bouncycastle.jce.provider.JDKKeyFactory$EC.engineGeneratePublic (:-1)
(.printStackTrace *e)
;; java.security.spec.InvalidKeySpecException: java.lang.NullPointerException
;; at org.bouncycastle.jce.provider.JDKKeyFactory$EC.engineGeneratePublic(Unknown Source)
;; at java.security.KeyFactory.generatePublic(KeyFactory.java:328)
;; at adhoc.ecdsa_mismatch$read_pubkey.invokeStatic(ecdsa_mismatch.clj:16)
;; at adhoc.ecdsa_mismatch$read_pubkey.invoke(ecdsa_mismatch.clj:14)
其他信息
使用NIST P-256曲线生成密钥:
Additional info
Generating a key with the NIST P-256 curve:
$ openssl ecparam -name prime256v1 -genkey -noout -outform DER | openssl ec -inform DER -pubout -outform DER > prime256v1.public.der
从磁盘加载prime256v1
:
(println (mm/read-pubkey "prime256v1.public.der"))
;; #object[org.bouncycastle.jce.provider.JCEECPublicKey 0x72369051 EC Public Key
;; X: 5a690a647dc4b7e80f71f15212b08686c1f717ada7198fa8a0b8c93cec16ecb
;; Y: 30be46137f328766ef8686675f118760ab0c96c52275bf00cf56097333ea6487
;; ]
公钥的内容:
$ base64 secp256k1.public.der
MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEsipNgzBpQ0CLgZNw+LhASmh4KmGXnJsOC2dfzq5cVwMn
HfsfHGphaGvZTNoc/lUVrr+ICFK/2D/9up9hHHHHWg==
$ base64 prime256v1.public.der
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEBaaQpkfcS36A9x8VISsIaGwfcXracZj6iguMk87B
bsswvkYTfzKHZu+GhmdfEYdgqwyWxSJ1vwDPVglzM+pkhw==
推荐答案
解决方案是Java-或此版本的BouncyCastle-不支持secp256k1
椭圆曲线!在openssl调用中使用更常见的曲线prime256v1
(NIST P-256)生成一个我可以读取的密钥.
The solution is that Java -- or perhaps this version of BouncyCastle -- does not support the secp256k1
elliptic curve! Using the far more common curve prime256v1
(NIST P-256) in the openssl call produces a key that I can read.
示例成功输出:
#<JCEECPublicKey EC Public Key
X: 89cfd7dfb455e6ea51e578e9ea3505ba1e44a0a5f126e3b280611cf6bb467653
Y: 565eb189ef15b8ff1b72824a7f0418a7df205797a86c8f30961e9bf0deaaa0c3
>
这篇关于无法从Java中读取OpenSSL生成的ECDSA密钥:InvalidKeySpecException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!