【问题标题】:How to load PEM encoded Elliptic Curve public keys into Bouncy Castle?如何将 PEM 编码的椭圆曲线公钥加载到 Bouncy Castle 中?
【发布时间】:2016-11-05 02:59:51
【问题描述】:

我有一个 PEM 编码的椭圆曲线公钥,我正试图将它加载到 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。我已经在 J​​avaScript(实际上是 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-----

【问题讨论】:

    标签: java clojure bouncycastle pem elliptic-curve


    【解决方案1】:

    做了一点按摩,我终于设法加载它:

    (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))
    

    【讨论】:

      【解决方案2】:

      既然你有 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()

      【讨论】:

        猜你喜欢
        • 2017-06-15
        • 2011-12-21
        • 1970-01-01
        • 2020-03-04
        • 2012-07-05
        • 1970-01-01
        • 2015-08-18
        • 2020-03-08
        • 2018-10-06
        相关资源
        最近更新 更多