Skip to content

Instantly share code, notes, and snippets.

@destan
Last active July 9, 2024 08:22
Show Gist options
  • Save destan/b708d11bd4f403506d6d5bb5fe6a82c5 to your computer and use it in GitHub Desktop.
Save destan/b708d11bd4f403506d6d5bb5fe6a82c5 to your computer and use it in GitHub Desktop.
Parse RSA public and private key pair from string in Java
#!/usr/bin/env bash
openssl genrsa -out private_key.pem 4096
openssl rsa -pubout -in private_key.pem -out public_key.pem
# convert private key to pkcs8 format in order to import it from Java
openssl pkcs8 -topk8 -in private_key.pem -inform pem -out private_key_pkcs8.pem -outform pem -nocrypt
import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
/**
* This file is intended to be used on a IDE for testing purposes.
* ClassLoader.getSystemResource won't work in a JAR
*/
public class Main {
public static void main(String[] args) throws InvalidKeySpecException, NoSuchAlgorithmException, IOException, URISyntaxException {
String privateKeyContent = new String(Files.readAllBytes(Paths.get(ClassLoader.getSystemResource("private_key_pkcs8.pem").toURI())));
String publicKeyContent = new String(Files.readAllBytes(Paths.get(ClassLoader.getSystemResource("public_key.pem").toURI())));
privateKeyContent = privateKeyContent.replaceAll("\\n", "").replace("-----BEGIN PRIVATE KEY-----", "").replace("-----END PRIVATE KEY-----", "");
publicKeyContent = publicKeyContent.replaceAll("\\n", "").replace("-----BEGIN PUBLIC KEY-----", "").replace("-----END PUBLIC KEY-----", "");;
KeyFactory kf = KeyFactory.getInstance("RSA");
PKCS8EncodedKeySpec keySpecPKCS8 = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKeyContent));
PrivateKey privKey = kf.generatePrivate(keySpecPKCS8);
X509EncodedKeySpec keySpecX509 = new X509EncodedKeySpec(Base64.getDecoder().decode(publicKeyContent));
RSAPublicKey pubKey = (RSAPublicKey) kf.generatePublic(keySpecX509);
System.out.println(privKey);
System.out.println(pubKey);
}
}
@TavenYin
Copy link

Thanks!

@Nallani9
Copy link

Nallani9 commented Mar 30, 2021

Getting NullPointerException, I have files in the root directory ??

@samiraghayarov
Copy link

Tesekkurler kardes!

@ytahrijo
Copy link

ytahrijo commented May 6, 2021

I got this error Illegal base64 character d
Do you have an idea ?

@tmuerell
Copy link

Thanks for this! 👍

@turkdogantdx
Copy link

Thanks 😄

@bronejeffries
Copy link

thanks man, saved my day

@supejuice
Copy link

Thanks man, saved my day

@devToroko
Copy link

thanks!!!

@and-petrenko
Copy link

Thanks, it was helpful!

@felixcarpena
Copy link

Thanks!!! ❤️

@ubaid4j
Copy link

ubaid4j commented Dec 20, 2022

Thanks, it worked like a charm.

@KhawanC
Copy link

KhawanC commented Dec 26, 2022

For those who are getting "Illegal base64 character d" error, here is the solution.

There is a regex missing in the public/privateKeyContent. Just add it at the end of the statment --> .replaceAll("\s", "")

@chmonk
Copy link

chmonk commented Jan 31, 2023

thanks a lot! save my day!!

@ssm498
Copy link

ssm498 commented Apr 13, 2023

For @KhawanC comment on 'illegal character d', its .replaceAll("\\s", "") for ALL whitespace characters (two backward slashes)
... ahhh I see the mistake, when we type in two '\' '\' github automatically removes one before posting :)

@thar0x29a
Copy link

Saved many of us. Thank you.

@hallundbaek
Copy link

hallundbaek commented Jun 25, 2023

Rewrote the java part to a Kotlin function that returns a KeyPair:

import java.nio.file.Files
import java.security.KeyFactory
import java.security.KeyPair
import java.security.spec.PKCS8EncodedKeySpec
import java.security.spec.X509EncodedKeySpec
import java.util.*
import kotlin.io.path.Path

fun readKeyPair(
  publicKeyPath: String,
  privateKeyPath: String,
): KeyPair =
  KeyFactory.getInstance("RSA").let { keyFactory ->
    KeyPair(
      keyFactory.generatePublic(
        X509EncodedKeySpec(
          Base64.getDecoder().decode(
            String(Files.readAllBytes(Path(publicKeyPath)))
                .replace("\n", "")
                .replace("-----BEGIN PUBLIC KEY-----", "")
                .replace("-----END PUBLIC KEY-----", "")
          )
        )
      ),
      keyFactory.generatePrivate(
        PKCS8EncodedKeySpec(
          Base64.getDecoder().decode(
            String(Files.readAllBytes(Path(privateKeyPath)))
                .replace("\n", "")
                .replace("-----BEGIN PRIVATE KEY-----", "")
                .replace("-----END PRIVATE KEY-----", "")
          )
        )
      )
    )
  }

@hungchu0912
Copy link

For anyone using java > 17, if you getting error at line 'Base64.getDecoder().decode(privateKeyContent)'. Replace it with getMimeDecoder() might work.
Base64.getMimeDecoder().decode(privateKeyContent)

@bithexe
Copy link

bithexe commented Jul 9, 2024

Thank you! Still helpful in 2024... 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment