我有一个PEM编码的Elliptic Curve公钥,我正试图加载到Bouncy Castle中,到目前为止我尝试的所有内容都失败了。这是我正在尝试加载的密钥示例:
-----BEGIN PUBLIC KEY-----
MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQBhsFCcWY2GaiN1BjPEd1v+ESKO6/0
D0sUR4y1amHnOr3FZx6TdqdoSBqxownQrnAKGCwagGxUb7BWwPFgHqKQJHgBq+J7
F+6m5SKAEL1wS5pqya91N7oudF3yFW8oZRE4RQRdSLl3fV2aVXKwGDXciwhUhw8k
x5OS4iZpMAY+LI4WVGU=
-----END PUBLIC KEY-----
它由NodeJS Crypto模块生成,曲线名称为secp521r1。它稍后由npm package key-encoder编码到PEM中。我已经在JavaScript(实际上是ClojureScript)中使用它来验证签名,现在我需要使用Java验证服务器上的签名(实际上是Clojure)。
我尝试从密钥中移除防护,转换为byte []并创建X509EncodedKeySpec。那没用。它崩溃了:
InvalidKeySpecException encoded key spec not recognised org.bouncycastle.jcajce.provider.asymmetric.util.BaseKeyFactorySpi.engineGeneratePublic (:-1)
我用来加载密钥的代码:
KeyFactory.
getInstance("ECDSA", "BC").
generatePublic(new X509EncodedKeySpec(publicKey.getBytes()))
以防万一,这是我的Clojure代码:
(-> (KeyFactory/getInstance "ECDSA")
(.generatePublic (X509EncodedKeySpec. (.getBytes public-key))))
我也尝试过PKCS8EncodedKeySpec,但是我收到了错误:
InvalidKeySpecException key spec not recognised org.bouncycastle.jcajce.provider.asymmetric.util.BaseKeyFactorySpi.engineGeneratePublic (:-1)
我也在这里试过这个方法:https://gist.github.com/wuyongzheng/0e2ed6d8a075153efcd3#file-ecdh_bc-java-L47-L50但是当运行decodePoint时我收到错误:
IllegalArgumentException Invalid point encoding 0x4d org.bouncycastle.math.ec.ECCurve.decodePoint (:-1)
当我移除警卫并且:
IllegalArgumentException Invalid point encoding 0x2d org.bouncycastle.math.ec.ECCurve.decodePoint (:-1)
守卫。
任何想法我做错了什么或如何解决它?
此外,如果它有帮助,这是私钥:
-----BEGIN EC PRIVATE KEY-----
MIHbAgEBBEEjNeo52qeffbIQvSxRcWAPlyJjeEOov2JNxxwWKCtlowi07HsYNNyE
jFDdSn8tSYAGx0rROrgpGuuJoG0zarPKz6AHBgUrgQQAI6GBiQOBhgAEAYbBQnFm
NhmojdQYzxHdb/hEijuv9A9LFEeMtWph5zq9xWcek3anaEgasaMJ0K5wChgsGoBs
VG+wVsDxYB6ikCR4AaviexfupuUigBC9cEuaasmvdTe6LnRd8hVvKGUROEUEXUi5
d31dmlVysBg13IsIVIcPJMeTkuImaTAGPiyOFlRl
-----END EC PRIVATE KEY-----
一切似乎都是有效的:
$ openssl ec -in private.pem -pubout
read EC key
writing EC key
-----BEGIN PUBLIC KEY-----
MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQBhsFCcWY2GaiN1BjPEd1v+ESKO6/0
D0sUR4y1amHnOr3FZx6TdqdoSBqxownQrnAKGCwagGxUb7BWwPFgHqKQJHgBq+J7
F+6m5SKAEL1wS5pqya91N7oudF3yFW8oZRE4RQRdSLl3fV2aVXKwGDXciwhUhw8k
x5OS4iZpMAY+LI4WVGU=
-----END PUBLIC KEY-----
答案 0 :(得分:2)
做了一些按摩我终于设法加载了它:
(require '[clojure.string :as s])
(import '[java.security KeyFactory]
'[java.security.spec X509EncodedKeySpec]
'[java.util Base64])
(def public-key "-----BEGIN PUBLIC KEY-----
MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQBhsFCcWY2GaiN1BjPEd1v+ESKO6/0
D0sUR4y1amHnOr3FZx6TdqdoSBqxownQrnAKGCwagGxUb7BWwPFgHqKQJHgBq+J7
F+6m5SKAEL1wS5pqya91N7oudF3yFW8oZRE4RQRdSLl3fV2aVXKwGDXciwhUhw8k
x5OS4iZpMAY+LI4WVGU=
-----END PUBLIC KEY-----")
(as-> public-key key
(s/replace key "-----BEGIN PUBLIC KEY-----" "")
(s/replace key "-----END PUBLIC KEY-----" "")
(s/replace key #"\s" "")
(.decode (Base64/getDecoder) key)
(X509EncodedKeySpec. key)
(.generatePublic (KeyFactory/getInstance "ECDSA" "BC") key))
答案 1 :(得分:1)
既然你有BC,它可以dePEMify而不是'手工'(我只做普通的Java):
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
Reader rdr = new StringReader("-----BEGIN PUBLIC KEY-----\n"
+"MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQBhsFCcWY2GaiN1BjPEd1v+ESKO6/0\n"
+"D0sUR4y1amHnOr3FZx6TdqdoSBqxownQrnAKGCwagGxUb7BWwPFgHqKQJHgBq+J7\n"
+"F+6m5SKAEL1wS5pqya91N7oudF3yFW8oZRE4RQRdSLl3fV2aVXKwGDXciwhUhw8k\n"
+"x5OS4iZpMAY+LI4WVGU=\n" +"-----END PUBLIC KEY-----\n"); // or from file etc.
org.bouncycastle.util.io.pem.PemObject spki = new org.bouncycastle.util.io.pem.PemReader(rdr).readPemObject();
PublicKey key = KeyFactory.getInstance("EC","BC").generatePublic(new X509EncodedKeySpec(spki.getContent()));
System.out.println (key.getAlgorithm() + " " + ((ECPublicKey)key).getW().toString());
Example output:
EC java.security.spec.ECPoint@47244700
仅供参考,PKCS8编码仅适用于私钥;见javadoc for java.security.Key.getFormat()