javassl-certificatersax509certificateazure-keyvault

Creating RSA Public Key From String throws exception


I've generated this test public key using open ssl command and I am trying to turn it into a public key using KeyFactory. It just keeps giving me an InvalidKeySpecException no matter what I try. Any advice at all would be appreciated.

private void prepKeys() {
    String AppKeyPub =
        "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";

    // create the key factory
    try {
        KeyFactory kFactory = KeyFactory.getInstance("RSA");
        // decode base64 of your key
        byte[] decoded = Base64.getDecoder().decode(AppKeyPub);
        // generate the public key
        X509EncodedKeySpec spec = new X509EncodedKeySpec(decoded);
        PublicKey publicKey = (PublicKey) kFactory.generatePublic(spec);

        System.out.println("Public Key: " + publicKey);

    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

The OpenSSL commands below are used to generate keys:

# generate a private key with the correct length 
openssl genrsa -out private-key.pem 3072 
# generate corresponding public key 
openssl rsa -in private-key.pem -pubout -out public-key.pem 
# optional: create a self-signed certificate 
openssl req -new -x509 -key private-key.pem -out cert.pem -days 360

Solution

  • I guess you copied the wrong key (maybe you wrongly copied the private key or the cert file). I use the your openssl commands to generate the public key (public-key.pem, the output file of the second command), then copy your code and change the public key to mine. The code works fine.

    Normally public key would be shorter than the key you put in the code.

    If you need to read public key from the cert. You can follow @Topaco's solution.

    // create the cert factory
    try {
        CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
        // decode base64 of your key
        byte[] decoded = Base64.getDecoder().decode(AppKeyPub);
        Certificate cert = certFactory.generateCertificate(new ByteArrayInputStream(decoded));
        PublicKey publicKey = cert.getPublicKey();
        System.out.println("Public Key: " + publicKey);
    
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }