【问题标题】:How to check if a file is pkcs#8 DER format in Java?如何检查文件是否为 Java 中的 pkcs#8 DER 格式?
【发布时间】:2021-12-29 09:44:52
【问题描述】:

我需要在上传文件时检查文件是否为Java中的pkcs#8 DER格式,我想也许可以使用PKCS8EncodedKeySpec和getFormat()。

class FileFormatePkcs8{
    public static void main(String[] args) {
    String filename = args[0];
        try {
            File f = new File(filename);
            byte[] encodedKey = new byte[(int)f.length()];
            PKCS8EncodedKeySpec pkcs8Key = new PKCS8EncodedKeySpec(encodedKey);
            if(pkcs8Key.getFormat().equals("PKCS#8")) {
                System.out.println("It's pkcs8.");
            }
            else {
                System.out.println("It's not pkcs8.");
            }
        }
        catch (Exception ex) {
            System.out.println("exception:"+ex.getMessage());
        }
    }

}

所有输入的文件都会得到“这是 pkcs8”。结果。我意识到“PKCS8EncodedKeySpec”将创建 pkcs#8 密钥,但我不知道使用哪个类来替换它。

注意:PKCS#8 和 DER 都需要检查,所以我认为 org.bouncycastle.openssl.PEMParser 可以忽略。还是我走错了路?

【问题讨论】:

    标签: java der pkcs#8


    【解决方案1】:

    首先,您实际上根本没有读取文件的内容。您只需创建一个与文件 size 相同的空缓冲区。由于此缓冲区不包含任何数据,因此非存在数据不是 PKCS8 格式,也不是 JKS 格式,也不是比特币钱包格式,也不是任何其他格式。 (注意不用多步,你可以直接使用byte[] data = Files.readAllBytes(Paths.get(filename)))。

    第二,there are two PKCS8 DER formats

    OOTB Java 明显支持 PKCS8 未加密(清除)PrivateKeyInfo如果您知道密钥适用的算法(RSA、DSA、ECDSA/ECDH 等)。如果这样做,只需为该算法调用KeyFactory.getInstance,然后使用包含(据称)PKCS8-clear 的PKCS8EncodedKeySpec 调用.generatePrivateKey,如果它返回 PrivateKey 的适当子类(并且不抛出异常)那么该算法的数据实际上是 PKCS8-clear 。如果您不知道算法,但只允许或可能使用有限的一组,您可以简单地依次尝试每个算法,看看是否有任何(以及哪个)有效。

    否则,您必须自己解析 ASN.1(可能,但很重要),或者使用 BouncyCastle(但不是 PEM 部分):调用 org.bouncycastle.asn1.pkcs.PrivateKeyInfo.getInstance(der),如果成功,输入数据要么是 PKCS8-clear 要么很好的模仿。

    对于 PKCS8 加密,Java 确实公开javax.crypto.EncryptedPrivateKeyInfo;只需在数据上调用构造函数,如果它不抛出数据,则看起来像 PKCS8 加密。然而,这并没有检查这些数据是否可以被解密,并且在解密时实际上是一个私钥,因为它应该是;为此,如果您知道密码,请使用 epki.getKeySpec() 并结合检查结果声称的 PKCS8-clear 如上所述。

    【讨论】:

    • 逻辑正确,非常感谢。但是我发现 privateKeyInfo 和 encryptedPrivateKeyInfo 的逻辑无法检查从 PEM 格式转换的 DER 格式密钥。例如。 openssl genrsa -out rsa_private_key.pem 1024; openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform DER -nocrypt -out pkcs8-noencryp1.der; openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform DER -v1 PBE-SHA1-3DES -out pkcs8-encryp.der,逻辑可以检查pkcs8-noencryp1.derpkcs8-encryp.der,但不能检查pkcs8-noencryp-pem-to-der.der
    • pkcs8-noencryp-pem-to-der.deropenssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt -out pkcs8-noencryp.pem; openssl pkcs8 -outform der -in pkcs8-noencryp.pem -out pkcs8-noencryp-pem-to-der.der -nocrypt产生的,你知道是什么问题吗?
    • 第二条评论中的命令不会生成 PKCS8 文件;特别是第二个命令没有 -topk8 并写入 legacy (PKCS1) DER 文件而不是 PKCS8 DER 文件。所以没有问题;代码正确检测到文件不是 PKCS8。
    • 太棒了!就是这样,感谢您的大力帮助!
    猜你喜欢
    • 1970-01-01
    • 2011-05-21
    • 2021-04-17
    • 1970-01-01
    • 2015-11-17
    • 1970-01-01
    • 1970-01-01
    • 2016-11-01
    • 1970-01-01
    相关资源
    最近更新 更多