2016-11-05 267 views
5

我有一個PEM編碼的橢圓曲線公鑰,我試圖加載到Bouncy Castle,到目前爲止我嘗試的所有東西都失敗了。這是關鍵,我想負載的例子:如何將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中。我已經在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----- 

回答

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

既然你有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 [email protected] 

僅供參考,PKCS8編碼僅用於私鑰;見javadoc for java.security.Key.getFormat()

相關問題