Search code examples
javaopensslrsabouncycastle

Java and Openssl generates different length of public keys for same private key


I used java to generate public key out of private key as follows,

    Security.addProvider(new BouncyCastleProvider());
    KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "BC");
    kpg.initialize(2048);
    KeyPair kp = kpg.generateKeyPair();
    PrivateKey priv = kp.getPrivate();
    RSAPrivateCrtKey rsaCrtKey = (RSAPrivateCrtKey) priv;
    RSAPublicKeySpec keyspecPublic =  new RSAPublicKeySpec(rsaCrtKey.getModulus(), rsaCrtKey.getPublicExponent());
    KeyFactory kf = KeyFactory.getInstance("RSA");
    PublicKey  publicKey2 = kf.generatePublic(keyspecPublic);
    String publicString = Base64.getMimeEncoder().encodeToString(publicKey2.getEncoded());
                StringBuilder sb = new StringBuilder("");
    sb.append("\"-----BEGIN PUBLIC KEY-----\\n")
       .append(publicString)
       .append("\\n-----END PUBLIC KEY-----");

And I generate public key using openssl as follows for same private key,

openssl rsa -in private.key -pubout -out public.key

But above two methods generate different lengths of strings as public key. Am I doing something wrong here?

public key from java code:

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6UkqbaGp7wOx2vrtqxmX/22ixKZcZPfZ
xXAawIst+AsWyNS+99MxnilstLIBKd6BCzJJsAa2I0ks43mnNZbkx1f1um+tQpXuTMbTh5MRprPn
jmX6aF+JXJbXATKhabTIQcCdpnrMi6scp9nWYkFdxVMfvo1gyThzfPwPgCO4eRFo1IkwZuergkl7
e0+U7WonqzFEb0joy5P78U+K8HebDW7nbS8zliq3DH2FI9yvEK3LeEN+Sa5icMWlERGv+7FCJVIH
CjBYfzaRZD9qqld/AnAEkCVt38SfSqWJECsnJYUW90WuFd8IxUVPS0TMfFMQhJFMT3eGweBOUb/b
pDm/hQIDAQAB
-----END PUBLIC KEY-----

Public key from openssl :

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6UkqbaGp7wOx2vrtqxmX
/22ixKZcZPfZxXAawIst+AsWyNS+99MxnilstLIBKd6BCzJJsAa2I0ks43mnNZbk
x1f1um+tQpXuTMbTh5MRprPnjmX6aF+JXJbXATKhabTIQcCdpnrMi6scp9nWYkFd
xVMfvo1gyThzfPwPgCO4eRFo1IkwZuergkl7e0+U7WonqzFEb0joy5P78U+K8Heb
DW7nbS8zliq3DH2FI9yvEK3LeEN+Sa5icMWlERGv+7FCJVIHCjBYfzaRZD9qqld/
AnAEkCVt38SfSqWJECsnJYUW90WuFd8IxUVPS0TMfFMQhJFMT3eGweBOUb/bpDm/
hQIDAQAB
-----END PUBLIC KEY-----

Solution

  • The keys are identical, and will decode to the same byte content.

    Formatting-wise, the Java one is wrapped at 76 columns and the OpenSSL one is wrapped at 64 columns.

    If you want to make the wrapping consistent, use the Base64.getMimeEncoder(int lineLength, byte[] lineSeparator) overloaded method that lets you specify the line length and pass 64 as the lineLength parameter.

    Base64.getMimeEncoder(64, new byte[] {'\r', '\n'});