How to load PEM Elliptic Curve public keys into Bouncy Castle?

I have a public key for a POP-encoded elliptic curve that I am trying to upload to Bouncy Castle, and everything I have tried so far fails. This is an example of the key I'm trying to download:

-----BEGIN PUBLIC KEY----- MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQBhsFCcWY2GaiN1BjPEd1v+ESKO6/0 D0sUR4y1amHnOr3FZx6TdqdoSBqxownQrnAKGCwagGxUb7BWwPFgHqKQJHgBq+J7 F+6m5SKAEL1wS5pqya91N7oudF3yFW8oZRE4RQRdSLl3fV2aVXKwGDXciwhUhw8k x5OS4iZpMAY+LI4WVGU= -----END PUBLIC KEY----- 

It is generated by NodeJS Crypto , and the curve name is secp521r1. Later it is encoded in PEM using the npm key-encoder package . I already used it in JavaScript (actually ClojureScript) to verify the signature, and now I need to verify the signature on the server with Java (Clojure actually).

I tried to remove the security features from the key by covering with a [] byte and creating an X509EncodedKeySpec. This did not work. He crashed:

 InvalidKeySpecException encoded key spec not recognised org.bouncycastle.jcajce.provider.asymmetric.util.BaseKeyFactorySpi.engineGeneratePublic (:-1) 

The code I use to download the key is:

 KeyFactory. getInstance("ECDSA", "BC"). generatePublic(new X509EncodedKeySpec(publicKey.getBytes())) 

Just in case, this is my Clojure code:

 (-> (KeyFactory/getInstance "ECDSA") (.generatePublic (X509EncodedKeySpec. (.getBytes public-key)))) 

I also tried PKCS8EncodedKeySpec but got an error:

 InvalidKeySpecException key spec not recognised org.bouncycastle.jcajce.provider.asymmetric.util.BaseKeyFactorySpi.engineGeneratePublic (:-1) 

I also tried this method here: https://gist.github.com/wuyongzheng/0e2ed6d8a075153efcd3#file-ecdh_bc-java-L47-L50 , but when I start decodePoint I get an error:

 IllegalArgumentException Invalid point encoding 0x4d org.bouncycastle.math.ec.ECCurve.decodePoint (:-1) 

when I removed the guards and:

 IllegalArgumentException Invalid point encoding 0x2d org.bouncycastle.math.ec.ECCurve.decodePoint (:-1) 

with protection.

Any ideas what I'm doing wrong or how to fix it?

Also, in case this helps, this is the private key:

 -----BEGIN EC PRIVATE KEY----- MIHbAgEBBEEjNeo52qeffbIQvSxRcWAPlyJjeEOov2JNxxwWKCtlowi07HsYNNyE jFDdSn8tSYAGx0rROrgpGuuJoG0zarPKz6AHBgUrgQQAI6GBiQOBhgAEAYbBQnFm NhmojdQYzxHdb/hEijuv9A9LFEeMtWph5zq9xWcek3anaEgasaMJ0K5wChgsGoBs VG+wVsDxYB6ikCR4AaviexfupuUigBC9cEuaasmvdTe6LnRd8hVvKGUROEUEXUi5 d31dmlVysBg13IsIVIcPJMeTkuImaTAGPiyOFlRl -----END EC PRIVATE KEY----- 

and everything seems valid:

 $ 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----- 
+5
source share
2 answers

With a little massage, I was finally able to download it:

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

Since you have BC, it can dePEMify instead of doing it β€œmanually” (I am doing just plain 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 

FYI, PKCS8 encoding is for private keys only; see javadoc for java.security.Key.getFormat()

+1
source

Source: https://habr.com/ru/post/1259307/


All Articles