如何在 Java 中检查文件是否为 pkcs#8 DER 格式?

How to check if a file is pkcs#8 DER format in Java?

我在上传文件的时候需要在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());
        }
    }

}

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

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

首先,您实际上根本没有读取文件的内容。您只需创建一个与文件相同 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,如果它 returns 的适当子类PrivateKey(并且不会抛出异常)然后数据实际上是 PKCS8-clear and 该算法。如果您不知道该算法,但只允许或可能使用有限的一组算法,您可以简单地依次尝试每个算法,看看是否有任何(和哪个)有效。

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

对于 PKCS8 加密,Java 暴露 javax.crypto.EncryptedPrivateKeyInfo;只需对数据调用构造函数,如果它不抛出数据,则数据看起来像 PKCS8 加密的。但是,这不会检查此数据是否可以解密,并且解密后实际上应该是一个私钥;为此,如果您知道密码,请结合使用 epki.getKeySpec() 并检查上面声称的 PKCS8-clear。