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

时间:2017-03-20 18:48:09

标签: java cryptography bouncycastle

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

我得到的是:

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

AsymmetricKeyParameter keyParameters = PublicKeyFactory.createKey(keyBytes);

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

然后:

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

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

2 个答案:

答案 0 :(得分:1)

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

像这样的东西

 //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的每个实例都具有键的参数,并且可以将它们提供给此way中的X509EncodedKeySpec的构造函数。但我认为上面的代码更简单

答案 1 :(得分:1)

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