Parsing certs/keys from Strings in Scala
I found it surprisingly difficult to get a straight answer online about how to parse the text of an RSA key-pair or certificate into their corresponding Java objects. Here's a basic step-by-step of how to do that. (All of this should basically apply to Java as well). A full example is at the bottom.

Create a factory what you're trying to decode.

1
// For X.509 certificates
2
val x509CertFactory: CertificateFactory = CertificateFactory.getInstance("X.509")
3
4
// For RSA keys
5
val rsaKeyFactory: KeyFactory = KeyFactory.getInstance("RSA")
Copied!
1
def stripCertText(certText: String): String =
2
certText
3
.stripMargin
4
.replace("\n", "")
5
.replace("-----BEGIN CERTIFICATE-----", "")
6
.replace("-----END CERTIFICATE-----", "")
7
8
def stripPrivateKeyText(keyText: String): String =
9
keyText
10
.stripMargin
11
.replace("\n", "")
12
.replace("-----BEGIN PRIVATE KEY-----", "")
13
.replace("-----END PRIVATE KEY-----", "")
14
15
def stripPublicKeyText(keyText: String): String =
16
keyText
17
.stripMargin
18
.replace("\n", "")
19
.replace("-----BEGIN PUBLIC KEY-----", "")
20
.replace("-----END PUBLIC KEY-----", "")
Copied!
The header/footer tag text may be different depending on what type of key you're decoding.

Decode base-64

1
val bytes = Base64.getDecoder.decode(strippedKeyText)
Copied!

Generate certificate/key

1
val x509Cert: X509Certificate = x509CertFactory
2
.generateCertificate(new ByteArrayInputStream(certBytes))
3
.asInstanceOf[X509Certificate] // Needs to get cast because CertificateFactory is lame
4
5
val rsaPublicKey: PublicKey = rsaKeyFactory.generatePublic(new X509EncodedKeySpec(bytes))
6
val rsaPrivateKey: PrivateKey = rsaKeyFactory.generatePrivate(new PKCS8EncodedKeySpec(bytes))
Copied!
Use the EncodedKeySpec based on the type of your keys. In this example, I used X509EncodedKeySpec for the public key and PKCS8EncodedKeySpec for the private key.
The certificate factory just takes in a ByteArrayInputStream.

Full example for parsing a certificate:

1
import java.io.ByteArrayInputStream
2
import java.security.cert.{ CertificateFactory, X509Certificate }
3
import java.util.Base64
4
5
val certText: String = "-----BEGIN CERTIFICATE-----\nMIIDHDCCAgSgAwIBAgIIW <...> IeilJ1C7Xtj+hKJEsk=-----END CERTIFICATE-----\n"
6
val factory: CertificateFactory = CertificateFactory.getInstance("X.509")
7
val strippedCertText: String = certText
8
.stripMargin
9
.replace("\n", "")
10
.replace("-----BEGIN CERTIFICATE-----", "")
11
.replace("-----END CERTIFICATE-----", "")
12
val certBytes: Array[Byte] = Base64.getDecoder.decode(strippedCertText)
13
val certByteArrayInputStream: ByteArrayInputStream = new ByteArrayInputStream(certBytes)
14
val x509Cert: X509Certificate = factory.generateCertificate(certByteArrayInputStream).asInstanceOf[X509Certificate]
Copied!
Last modified 2yr ago