javaencryptionbouncycastlejce

convert Bouncy Castle's AsymmetricCipherKeyPair (RSA) to java.security.KeyPair


I am trying to automate generation of CA and certificates for our E2E testing. I started with Bouncy Castle and I have managed to generate CA cert and machine cert. However, now I need to convert the RSA keypair represented by BC' org.bouncycastle.crypto.AsymmetricCipherKeyPair to java.security.KeyPair. I cannot seem to find a way to do this.


Solution

  • There's probably more than one way to do it, but here is one example:

    import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
    import org.bouncycastle.crypto.util.PrivateKeyInfoFactory;
    import org.bouncycastle.crypto.util.SubjectPublicKeyInfoFactory;
        
    import java.security.KeyFactory;
    import java.security.KeyPair;
    import java.security.spec.PKCS8EncodedKeySpec;
    import java.security.spec.X509EncodedKeySpec;
    
    private static KeyPair convertBcToJceKeyPair(AsymmetricCipherKeyPair bcKeyPair) throws Exception {
        byte[] pkcs8Encoded = PrivateKeyInfoFactory.createPrivateKeyInfo(bcKeyPair.getPrivate()).getEncoded();
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(pkcs8Encoded);
        byte[] spkiEncoded = SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo(bcKeyPair.getPublic()).getEncoded();
        X509EncodedKeySpec spkiKeySpec = new X509EncodedKeySpec(spkiEncoded);
        KeyFactory keyFac = KeyFactory.getInstance("RSA");
        return new KeyPair(keyFac.generatePublic(spkiKeySpec), keyFac.generatePrivate(pkcs8KeySpec));
    }
    

    And here is an example to go in the other direction, to convert a java KeyPair to a Bouncy Castle AsymmetricCipherKeyPair.

    private static AsymmetricCipherKeyPair convertJceToBcKeyPair(KeyPair javaKeyPair) {
        RSAPublicKey javaRsaPub = (RSAPublicKey) javaKeyPair.getPublic();
        RSAKeyParameters bcRsaPub = new RSAKeyParameters(false, javaRsaPub.getModulus(), javaRsaPub.getPublicExponent());
        if (javaKeyPair.getPrivate() instanceof RSAPrivateCrtKey) {
            RSAPrivateCrtKey javaRsaPriv = (RSAPrivateCrtKey) javaKeyPair.getPrivate();
            RSAKeyParameters bcRsaPriv = new RSAPrivateCrtKeyParameters(
                    javaRsaPriv.getModulus(),
                    javaRsaPriv.getPublicExponent(),
                    javaRsaPriv.getPrivateExponent(),
                    javaRsaPriv.getPrimeP(),
                    javaRsaPriv.getPrimeQ(),
                    javaRsaPriv.getPrimeExponentP(),
                    javaRsaPriv.getPrimeExponentQ(),
                    javaRsaPriv.getCrtCoefficient()
            );
            return new AsymmetricCipherKeyPair(bcRsaPub, bcRsaPriv);
        } else {
            RSAPrivateKey javaRsaPriv = (RSAPrivateKey) javaKeyPair.getPrivate();
            RSAKeyParameters bcRsaPriv = new RSAKeyParameters(
                    true,
                    javaRsaPriv.getModulus(),
                    javaRsaPriv.getPrivateExponent()
            );
            return new AsymmetricCipherKeyPair(bcRsaPub, bcRsaPriv);
        }
    }