从不知道密钥算法的关键字节获取PublicKey

时间:2022-07-12 18:25:30

I have a byte array containing an encoded public key. I don't know the key algorithm. And I want to get the PublicKey object.

我有一个包含编码公钥的字节数组。我不知道关键算法。我想获得PublicKey对象。

What I have got is:

我得到的是:

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

AsymmetricKeyParameter keyParameters = PublicKeyFactory.createKey(keyBytes);

The keyParameters class can be RSAKeyParameters, ECPublicKeyParameters, ... so now I can know the key algorithm.

keyParameters类可以是RSAKeyParameters,ECPublicKeyParameters,...所以现在我可以知道密钥算法。

And then:

接着:

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

But I don't know if there's a more direct way to get the PublicKey. I mean, is there a direct way to get PublicKey from key bytes without the need to get first AsymmetricKeyParameter (and without the need to manually decode the key bytes) ?

但我不知道是否有更直接的方式来获取PublicKey。我的意思是,是否有直接的方法从关键字节获取PublicKey而无需首先获得AsymmetricKeyParameter(并且无需手动解码关键字节)?

2 个解决方案

#1


1  

I am afraid there is no direct way. It is needed to inspect the class created by bouncycastle to know the algorithm (better option than parse the key manually) and build the PublicKey using X509EncodedKeySpec

恐怕没有直接的办法。需要检查bouncycastle创建的类以了解算法(比手动解析密钥更好的选项)并使用X509EncodedKeySpec构建PublicKey

Something like this

像这样的东西

 //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 {
          ...
       }
 }

Each instance of AsymmetricKeyParameter has the parameters of the key, and they could be provided to the constructor of X509EncodedKeySpec in this way. But I think above code is simpler

AsymmetricKeyParameter的每个实例都具有键的参数,并且可以通过这种方式将它们提供给X509EncodedKeySpec的构造函数。但我认为上面的代码更简单

#2


1  

Here is a direct way (using Bouncy Castle API):

这是一种直接的方式(使用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);
    }

#1


1  

I am afraid there is no direct way. It is needed to inspect the class created by bouncycastle to know the algorithm (better option than parse the key manually) and build the PublicKey using X509EncodedKeySpec

恐怕没有直接的办法。需要检查bouncycastle创建的类以了解算法(比手动解析密钥更好的选项)并使用X509EncodedKeySpec构建PublicKey

Something like this

像这样的东西

 //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 {
          ...
       }
 }

Each instance of AsymmetricKeyParameter has the parameters of the key, and they could be provided to the constructor of X509EncodedKeySpec in this way. But I think above code is simpler

AsymmetricKeyParameter的每个实例都具有键的参数,并且可以通过这种方式将它们提供给X509EncodedKeySpec的构造函数。但我认为上面的代码更简单

#2


1  

Here is a direct way (using Bouncy Castle API):

这是一种直接的方式(使用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);
    }