有弹性的城堡-如何从JceOpenSSLPKCS8DecryptorProviderBuilder获取公钥信息

时间:2019-07-15 16:17:16

标签: java bouncycastle public-key

我有以下代码来提取私钥

    PEMParser parser = new PEMParser(new InputStreamReader(new ByteArrayInputStream(decoded)));
    Object object = parser.readObject();
    PEMDecryptorProvider provider = new JcePEMDecryptorProviderBuilder()
            .build(props.getProperty(KeytoolFlags.KEYPASS.name()).toCharArray());

    JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider(BouncyCastleProvider.PROVIDER_NAME);
    if (object instanceof PEMEncryptedKeyPair) {
        KeyPair pair = converter.getKeyPair(((PEMEncryptedKeyPair) object).decryptKeyPair(provider));
        return loadPublic ? pair.getPublic() : pair.getPrivate();
    } else if (object instanceof PEMKeyPair) {
        return loadPublic ? converter.getPublicKey(((PEMKeyPair) (object)).getPublicKeyInfo())
                : converter.getPrivateKey(((PEMKeyPair) (object)).getPrivateKeyInfo());
    } else {
        InputDecryptorProvider p2 = new JceOpenSSLPKCS8DecryptorProviderBuilder()
                .setProvider(BouncyCastleProvider.PROVIDER_NAME)
                .build(props.getProperty(KeytoolFlags.KEYPASS.name()).toCharArray());
        return converter.getPrivateKey(((PKCS8EncryptedPrivateKeyInfo) object).decryptPrivateKeyInfo(p2));
    }

我想从JceOpenSSLPKCS8DecryptorProviderBuilder的转换器中获取公钥。有什么办法吗?

谢谢

2 个答案:

答案 0 :(得分:1)

最简单的方法(虽然对我来说很丑陋)是将私钥“ back”转换为OpenSSL的“旧版”格式之一,然后PEMParser可以将其转换为{{1} }分为两个部分,可以从中选择公众。否则,必须根据密钥算法(也称为类型)来定制方法,但是可以更高效,我更喜欢。这两个选项供您考虑:

PEMKeyPair

答案 1 :(得分:0)

除了其他答案,这是将Ed25519私钥转换为公钥的一种方法:

private val bouncyCastleProvider = BouncyCastleProvider()
private val pkcs8pemKeyConverter = JcaPEMKeyConverter().setProvider(bouncyCastleProvider)

fun makeKeyPair(keyReader: Reader, passphrase: CharArray): KeyPair {
    var obj = PEMParser(keyReader).readObject()
    ...
    if (obj is PrivateKeyInfo) {
        val privateKey = pkcs8pemKeyConverter.getPrivateKey(obj)

        if (privateKey is EdDSAKey) {
            return KeyPair(genEd25519publicKey(privateKey, obj), privateKey)
        }

        ...
    }
    ...
}

private fun genEd25519publicKey(privateKey: EdDSAKey, keyInfo: PrivateKeyInfo): PublicKey {
    val privateKeyParameters = Ed25519PrivateKeyParameters(privateKey.encoded, 0)
    val publicKeyParameters = privateKeyParameters.generatePublicKey()
    val spi = SubjectPublicKeyInfo(keyInfo.privateKeyAlgorithm, publicKeyParameters.encoded)
    val factory = KeyFactory.getInstance(privateKey.algorithm, bouncyCastleProvider)
    return factory.generatePublic(X509EncodedKeySpec(spi.encoded))
}