import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.spec.*;

public class BadSpecChecks {
    public static void main(String[] args) throws Exception {
        KeyPairGenerator kg = KeyPairGenerator.getInstance("RSA");
        kg.initialize(2048);
        KeyPair pair = kg.generateKeyPair();

        KeyFactory factory = KeyFactory.getInstance("RSA");

        System.out.println("Since RSAPrivateCrtKeySpec inherits from RSAPrivateKeySpec, we'd expect this next line to return an instance of RSAPrivateKeySpec (because the private key has CRT parts). It doesn't.");
        KeySpec spec = factory.getKeySpec(pair.getPrivate(), RSAPrivateKeySpec.class);
        System.out.println(spec.getClass());

        System.out.println("This next line should give an InvalidKeySpec exception");
        try {
            spec = factory.getKeySpec(pair.getPublic(), FakeX509Spec.class);
            System.out.println("This line shouldn't be reached.");
        } catch (final InvalidKeySpecException ex) {
            System.out.println("Caught expected exception");
            ex.printStackTrace(System.out);
        }
    }

    public static class FakeX509Spec extends X509EncodedKeySpec {
        public FakeX509Spec(byte[] encodedKey) {
            super(encodedKey);
        }

        public FakeX509Spec(byte[] encodedKey, String algorithm) {
            super(encodedKey, algorithm);
        }
    }
}
