Reputation: 95
I have a .pem certificate and private key which I require for SSL. Doing so is trivial in Python:
import httpx
import ssl
sslcontext = ssl.create_default_context()
sslcontext.load_cert_chain(
"./public-cert.pem",
"./private-key.pem",
)
response = httpx.post(
url,
verify=sslcontext,
)
But I'd like do the same in Kotlin / Java. I've been going through the following article but I'm having issues handling the private key: https://developer.android.com/training/articles/security-ssl
I believe I must read the private key through a KeyFactory like such:
fun loadPrivateKey(path: Path): PrivateKey {
val keyText = InputStreamReader(FileInputStream(path.toString())).use {
it.readText()
.replace("-----BEGIN PRIVATE KEY-----\n", "")
.replace("-----END PRIVATE KEY-----", "")
}
val encoded = Base64.getDecoder().decode(keyText)
return KeyFactory.getInstance("RSA")
.generatePrivate(PKCS8EncodedKeySpec(encoded))
}
And pass it into the key store. However, decoding results in an error:
Illegal base64 character a
I would like to avoid handling it like this if possible: https://stackoverflow.com/a/8224863/13669284 I'm a little lost at this point and any guidance on this matter would be much appreciated.
Upvotes: 2
Views: 384
Reputation: 746
For basic encoding no line feed character allowed: Using java.util.Base64 Basic – Uses “The Base64 Alphabet” as specified in Table 1 of RFC 4648 and RFC 2045 for encoding and decoding operation. – Encoding: not add any line feed (line separator) character. – Decoding: not contain characters outside the Base64 Alphabet.
So you can replace all the occurrences of "\n" in the key:
fun loadPrivateKey(path: Path): PrivateKey {
val keyText = InputStreamReader(FileInputStream(path.toString())).use {
it.readText()
.replace("\n", "")
.replace("-----BEGIN PRIVATE KEY-----", "")
.replace("-----END PRIVATE KEY-----", "")
}
val encoded = Base64.getDecoder().decode(keyText)
return KeyFactory.getInstance("RSA")
.generatePrivate(PKCS8EncodedKeySpec(encoded))
}
Upvotes: 2