2017-03-20 2 views
1

J'ai un tableau d'octets contenant une clé publique codée. Je ne connais pas l'algorithme clé. Et je veux obtenir l'objet PublicKey.Obtenir PublicKey à partir des octets de clé ne connaissant pas l'algorithme de clé

Ce que j'ai est:

import org.bouncycastle.crypto.params.AsymmetricKeyParameter; 
import org.bouncycastle.crypto.util.PublicKeyFactory; 

AsymmetricKeyParameter keyParameters = PublicKeyFactory.createKey(keyBytes); 

La classe keyParameters peut être RSAKeyParameters, ECPublicKeyParameters, ... maintenant je peux savoir l'algorithme à clé.

Et puis:

KeyFactory keyFactory = KeyFactory.getInstance(keyAlgorithm); 
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); 
PublicKey publicKey = keyFactory.generatePublic(keySpec); 

Mais je ne sais pas s'il y a un moyen d'obtenir le PublicKey plus direct. Je veux dire, y a-t-il un moyen direct d'obtenir PublicKey à partir des octets de clé sans avoir besoin d'avoir d'abord AsymmetricKeyParameter (et sans avoir besoin de décoder manuellement les octets de clé)?

+0

connaissez-vous la longueur de la clé, les clés de la CE sont généralement plus courtes que les clés RSA. Avez-vous examiné le tableau d'octets dans un éditeur hexadécimal ou même un éditeur de texte? – zaph

+1

Quel est le problème avec votre code? Comme vous le dites, l'algorithme keyAlgorithm peut être connu en utilisant la classe AssymetricKeyParameters. A ma connaissance, il n'y a pas de conversion directe de AssymetricKeyParameters en java 'PublicKey' – pedrofb

+0

Cela ressemble à un problème de poule ou de l'oeuf (pour obtenir la clé, vous devez connaître l'algorithme, mais vous ne connaîtrez l'algorithme qu'après avoir objet clé). Je ne vois pas d'autre moyen de le résoudre que de faire if (keyParameters instanceof RSAKeyParameters) {utiliser l'algorithme RSA} 'et ainsi de suite –

Répondre

0

Je crains qu'il n'y ait pas de voie directe. Il est nécessaire d'inspecter la classe créée par bouncycastle savoir l'algorithme (meilleure option que d'analyser manuellement la clé) et construire le PublicKey en utilisant X509EncodedKeySpec

Quelque chose comme ça

//load key with Bouncycastle 
AsymmetricKeyParameter keyParameters = PublicKeyFactory.createKey(keyBytes); 

//get algorithm inspecting the created class 
String keyAlgorithm = extractKeyAlgorithm(keyParameters); 

//get public key 
KeyFactory keyFactory = KeyFactory.getInstance(keyAlgorithm); 
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); 
PublicKey publicKey = keyFactory.generatePublic(keySpec); 

public String extractKeyAlgorithm(AsymmetricKeyParameter keyParameters){ 

     if (keyParameters instanceof RSAKeyParameters){ 
      return "RSA"; 
     } else if (keyParameters instanceof DSAKeyParameters){ 
      return "DSA"; 
     } else { 
      ... 
     } 
} 

Chaque instance de AsymmetricKeyParameter a les paramètres de la clé, et ils pourraient être fournis au constructeur de X509EncodedKeySpec dans ce way. Mais je pense que le code ci-dessus est plus simple

1

Voici une manière directe (en utilisant Bouncy Castle API):

public PublicKey publicKeyParse(byte[] publicKeyBytes) { 
      InputStream pgpIn = PGPUtil.getDecoderStream(new ByteArrayInputStream(publicKeyBytes)); 
      PGPObjectFactory pgpFact = new PGPObjectFactory(pgpIn, new JcaKeyFingerprintCalculator()); 
      PGPPublicKeyRing pgpSecRing = (PGPPublicKeyRing) pgpFact.nextObject(); 
      PGPPublicKey publicKey = pgpSecRing.getPublicKey(); 
      JcaPGPKeyConverter converter = new JcaPGPKeyConverter(); 
      Provider bcProvider = new BouncyCastleProvider(); 
      converter.setProvider(bcProvider); 
      return converter.getPublicKey(publicKey); 
    }