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

Get PublicKey from key bytes not knowing the key algorithm

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

我得到的是:

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

AsymmetricKeyParameter keyParameters = PublicKeyFactory.createKey(keyBytes);

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

然后:

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

但是不知道有没有更直接的方式获取PublicKey。 我的意思是,是否有直接的方法从密钥字节获取 PublicKey 而无需获取第一个 AsymmetricKeyParameter(并且无需手动解码密钥字节)?

恐怕没有直接的方法。需要检查由 bouncycastle 创建的 class 以了解算法(比手动解析密钥更好的选择)并使用 X509EncodedKeySpec

构建 PublicKey

像这样

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

AsymmetricKeyParameter的每个实例都有key的参数,可以在中提供给X509EncodedKeySpec的构造函数。但是我觉得上面的代码更简单

这里有一个直接的方法(使用 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);
    }