Search code examples
javabouncycastleprivate-keygithub-app

How to get fingerprint from a pem file from Github App?


It's possible to generate a private key for Github Apps (Settings -> Developer Settings -> (Edit a GH App) -> "Generate a private key"). When it's generated I save locally a pem file and in UI there's an information about fingerprint of that key (SHA256:...).

enter image description here

How can I receive that fingerprint myself in Java code, given the pem file that I saved before?


Solution

  • The pem file that you saved contains both information about private and public key, so it's possible to get that information yourself.

    Information about verification of private keys is documented here and it's basically the following one-line command:

    openssl rsa -in PATH_TO_PEM_FILE -pubout -outform DER | openssl sha256 -binary | openssl base64
    

    In order to get that information in Java, you can use bouncycastle library that does the same chain of operations as above.

    public static String getFingerprint(final String pemContent) throws IOException {
        // openssl rsa -in PATH_TO_PEM_FILE -pubout -outform DER
        final PEMParser parser = new PEMParser(new StringReader(pemContent));
        final Object object = (PEMKeyPair) parser.readObject();
        final PEMKeyPair pemKeyPair = (PEMKeyPair) object;
        final SubjectPublicKeyInfo publicKeyInfo = pemKeyPair.getPublicKeyInfo();
        final ASN1Primitive asn1Primitive = publicKeyInfo.toASN1Primitive();
        final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        asn1Primitive.encodeTo(outputStream, "DER");
        final byte[] derBytes = outputStream.toByteArray();
    
        // openssl sha256 -binary
        MessageDigest instance = MessageDigest.getInstance("SHA-256");
        instance.update(derBytes);
        byte[] sha256bytes = instance.digest();
        
        // openssl base64
        return Base64.getEncoder().encodeToString(sha256bytes);
    }