在Kotlin / Java中使用证书和私钥进行POST请求身份验证的问题。

huangapple go评论73阅读模式
英文:

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 对象。这段代码会读取私钥文件,移除头部和尾部的标识,并解码为字节数组,然后使用 KeyFactoryPKCS8EncodedKeySpec 来生成私钥对象。请确保导入必要的类和处理异常情况。

注意:由于你要加载 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))
}

huangapple
  • 本文由 发表于 2020年10月22日 11:51:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/64475047.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定