如何将 PEM 编码的椭圆曲线公钥加载到 Bouncy Castle 中? [英] How to load PEM encoded Elliptic Curve public keys into Bouncy Castle?
问题描述
我有一个 PEM 编码的椭圆曲线公钥,我正在尝试将其加载到 Bouncy Castle 中,但到目前为止我尝试过的一切都失败了.这是我尝试加载的密钥示例:
I have a PEM encoded Elliptic Curve public key that I'm trying to load into Bouncy Castle and everything I tried so far is failing. This is an example of the key I'm trying to load:
-----BEGIN PUBLIC KEY-----
MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQBhsFCcWY2GaiN1BjPEd1v+ESKO6/0
D0sUR4y1amHnOr3FZx6TdqdoSBqxownQrnAKGCwagGxUb7BWwPFgHqKQJHgBq+J7
F+6m5SKAEL1wS5pqya91N7oudF3yFW8oZRE4RQRdSLl3fV2aVXKwGDXciwhUhw8k
x5OS4iZpMAY+LI4WVGU=
-----END PUBLIC KEY-----
由NodeJS Crypto模块生成,曲线名称为secp521r1.它稍后由 npm 包密钥编码器 编码为 PEM.我已经在 JavaScript(实际上是 ClojureScript)中使用它来验证签名,现在我需要使用 Java(实际上是 Clojure)来验证服务器上的签名.
It is generated by NodeJS Crypto module and the curve name is secp521r1. It's later on encoded into PEM by the npm package key-encoder. I already used it in JavaScript (ClojureScript actually) to verify a signature and now I need to verify the signature on the server with Java (Clojure actually).
我尝试从密钥中移除保护,转换为字节 [] 并创建 X509EncodedKeySpec.那没有用.它崩溃了:
I tried removing the guards from the key, coverting to a byte[] and creating a X509EncodedKeySpec. That didn't work. It crashed with:
InvalidKeySpecException encoded key spec not recognised org.bouncycastle.jcajce.provider.asymmetric.util.BaseKeyFactorySpi.engineGeneratePublic (:-1)
我用来加载密钥的代码:
The code to I'm using to load the key:
KeyFactory.
getInstance("ECDSA", "BC").
generatePublic(new X509EncodedKeySpec(publicKey.getBytes()))
以防万一,这是我的 Clojure 代码:
Just in case, this is my Clojure code:
(-> (KeyFactory/getInstance "ECDSA")
(.generatePublic (X509EncodedKeySpec. (.getBytes public-key))))
我也试过 PKCS8EncodedKeySpec 但我得到了错误:
I also tried PKCS8EncodedKeySpec but I got the error:
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 时出现错误:
I also tried this method here: https://gist.github.com/wuyongzheng/0e2ed6d8a075153efcd3#file-ecdh_bc-java-L47-L50 but when running decodePoint I get the error:
IllegalArgumentException Invalid point encoding 0x4d org.bouncycastle.math.ec.ECCurve.decodePoint (:-1)
当我移除警卫并:
IllegalArgumentException Invalid point encoding 0x2d org.bouncycastle.math.ec.ECCurve.decodePoint (:-1)
警卫在场.
任何想法我做错了什么或如何解决它?
Any ideas what I'm doing wrong or how to fix it?
另外,如果有帮助,这是私钥:
Also, in case it helps, this is the private key:
-----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-----
推荐答案
因为你有 BC,它可以 dePEMify 而不是手工"做(我只做普通的 Java):
Since you have BC, it can dePEMify instead of doing it 'by hand' (I only do plain Java):
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
Reader rdr = new StringReader("-----BEGIN PUBLIC KEY-----
"
+"MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQBhsFCcWY2GaiN1BjPEd1v+ESKO6/0
"
+"D0sUR4y1amHnOr3FZx6TdqdoSBqxownQrnAKGCwagGxUb7BWwPFgHqKQJHgBq+J7
"
+"F+6m5SKAEL1wS5pqya91N7oudF3yFW8oZRE4RQRdSLl3fV2aVXKwGDXciwhUhw8k
"
+"x5OS4iZpMAY+LI4WVGU=
" +"-----END PUBLIC KEY-----
"); // 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 以了解 java.security.Key.getFormat()
FYI, PKCS8 encoding is only for private keys; see javadoc for java.security.Key.getFormat()
这篇关于如何将 PEM 编码的椭圆曲线公钥加载到 Bouncy Castle 中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!