5 votes

Comment charger des clés publiques à courbe elliptique encodées PEM dans Bouncy Castle ?

J'ai une clé publique Elliptic Curve encodée en PEM que j'essaie de charger dans Bouncy Castle et tout ce que j'ai essayé jusqu'à présent échoue. Voici un exemple de la clé que j'essaie de charger :

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

Il est généré par NodeJS Crypto et le nom de la courbe est secp521r1. Elle est ensuite encodée en PEM par le module npm package key-encoder . Je l'ai déjà utilisé en JavaScript (ClojureScript en fait) pour vérifier une signature et maintenant j'ai besoin de vérifier la signature sur le serveur avec Java (Clojure en fait).

J'ai essayé de supprimer les gardes de la clé, de la convertir en byte[] et de créer une X509EncodedKeySpec. Cela n'a pas fonctionné. Il s'est écrasé avec :

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

Le code que j'utilise pour charger la clé :

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

Juste au cas où, voici mon code Clojure :

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

J'ai également essayé PKCS8EncodedKeySpec mais j'ai obtenu l'erreur :

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

J'ai également essayé cette méthode ici : https://gist.github.com/wuyongzheng/0e2ed6d8a075153efcd3#file-ecdh_bc-java-L47-L50 mais lorsque j'exécute decodePoint, j'obtiens l'erreur suivante :

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

lorsque j'ai enlevé les protections et :

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

avec les gardes.

Une idée de ce que je fais mal ou de la façon de résoudre le problème ?

De plus, si cela peut vous aider, voici la clé privée :

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

et tout semble être valable :

$ 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-----

2voto

Pablo Points 44881

En massant un peu, j'ai finalement réussi à le charger :

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

1voto

dave_thompson_085 Points 11995

Puisque vous avez BC, il peut déPEMifier au lieu de le faire 'à la main' (je ne fais que du Java simple) :

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

Pour information, l'encodage PKCS8 ne concerne que les clés privées ; voir javadoc pour java.security.Key.getFormat()

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X