英文:
Issues authenticating a post request with a certificate and private key in Kotlin / Java
问题
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.nio.file.Path;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
// Load private key from file
private PrivateKey loadPrivateKey(Path path) throws Exception {
String keyText = new String(
Files.readAllBytes(path))
.replace("-----BEGIN PRIVATE KEY-----\n", "")
.replace("-----END PRIVATE KEY-----", "");
byte[] encoded = Base64.getDecoder().decode(keyText);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(encoded));
}
你可以使用上面这段 Java 代码来加载 PEM 格式的私钥文件,并生成相应的 PrivateKey
对象。这段代码会读取私钥文件,移除头部和尾部的标识,并解码为字节数组,然后使用 KeyFactory
和 PKCS8EncodedKeySpec
来生成私钥对象。请确保导入必要的类和处理异常情况。
注意:由于你要加载 PEM 格式的私钥文件,代码中的 loadPrivateKey
函数假定输入的是符合 PEM 格式的私钥文件。如果你的私钥文件格式有变化,可能需要适当调整代码。
希望这能对你有所帮助!如有其他问题,请随时问我。
英文:
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.
答案1
得分: 2
对于基本编码,不允许使用换行字符:
使用 java.util.Base64
基本
- 使用 RFC 4648 和 RFC 2045 中表格 1 中指定的 "Base64 Alphabet" 来进行编码和解码操作。
- 编码:不添加任何换行(行分隔符)字符。
- 解码:不包含 Base64 字母表之外的字符。
因此,您可以替换密钥中所有的 "\n" 出现:
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))
}
英文:
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))
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论