Java 8破坏了我使用PKCS12的应用程序

Java 8破坏了我使用PKCS12的应用程序,java,pkcs#12,Java,Pkcs#12,2007年,我编写了一个小型java应用程序,可以对几个不同的PDF文档(带有我的签名图像)进行数字签名。在升级到Java8之前,我一直工作得很好 我现在遇到了错误: IOException: Unable to read private key from keystore e: java.io.IOException: unsupported PKCS12 secret value type 48 现在看来,Java8PKCS12无法存储密钥条目。这对我来说是一个至关重要的应用程序。我一天要

2007年,我编写了一个小型java应用程序,可以对几个不同的PDF文档(带有我的签名图像)进行数字签名。在升级到Java8之前,我一直工作得很好

我现在遇到了错误:

IOException: Unable to read private key from keystore
e: java.io.IOException: unsupported PKCS12 secret value type 48
现在看来,Java8PKCS12无法存储密钥条目。这对我来说是一个至关重要的应用程序。我一天要用几百次

我如何解决这个问题

以下是关键代码的简略版本:

String appPath =  SignPDF.class.getProtectionDomain().getCodeSource().getLocation().getPath();

String keytype  =  "pkcs12";
String keyfile  =  appPath + "DanVokt.pfx";
String keyimage =  appPath + "DanVokt.png";
String keypass  =  "xxxxxxxxx";

KeyStore ks = KeyStore.getInstance(keytype);
ks.load(new FileInputStream(keyfile), keypass.toCharArray());
String alias = (String)ks.aliases().nextElement();
PrivateKey key = (PrivateKey)ks.getKey(alias, keypass.toCharArray());
Certificate[] chain = ks.getCertificateChain(alias);

PdfReader reader = new PdfReader(ifile);
FileOutputStream fout = new FileOutputStream(ofile);

PdfStamper stp = PdfStamper.createSignature(reader, fout, '\0');
PdfSignatureAppearance sap = stp.getSignatureAppearance();
sap.setCrypto(key, chain, null, PdfSignatureAppearance.SELF_SIGNED);

// allow only printing
stp.setEncryption(null, keypass.getBytes(), PdfWriter.ALLOW_PRINTING,
                  PdfWriter.STANDARD_ENCRYPTION_128);
stp.close();
下面是一个堆栈tace:

$ signpdf "Timelog*" 1
Processing File: "Timelog - Current Week.pdf" 1
IOException: Unable to read private key from keystore
java.io.IOException: unsupported PKCS12 secret value type 48
    at sun.security.pkcs12.PKCS12KeyStore.loadSafeContents(PKCS12KeyStore.java:2197)
    at sun.security.pkcs12.PKCS12KeyStore.engineLoad(PKCS12KeyStore.java:2025)
    at java.security.KeyStore.load(KeyStore.java:1445)
    at SignPDF.main(SignPDF.java:61)
以下是版本和内部版本:

$ java -version
java version "1.8.0_131"
Java(TM) SE Runtime Environment (build 1.8.0_131-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode)
尝试使用keytool查看PKCS12(.pfx)文件:


我做了一些挖掘。这一变化似乎是某些密钥库API增强的一部分。(2013年1月)

具体测试如下:

        } else if (bagId.equals((Object)SecretBag_OID)) {
            DerInputStream ss = new DerInputStream(bagValue.toByteArray());
            DerValue[] secretValues = ss.getSequence(2);
            ObjectIdentifier secretId = secretValues[0].getOID();
            if (!secretValues[1].isContextSpecific((byte)0)) {
                throw new IOException(
                    "unsupported PKCS12 secret value type "
                                    + secretValues[1].tag);
            }
其中
!(isContextSpecific()
正在检查DERvalue的“标记”,以确保未设置上下文位。此测试失败

似乎解决方法是将这些密钥存储为DER值,并使用未设置位
0x80
的标记类型

另见:

  • PKCS12KeyStore.java-
  • java-
[已解决]

我创建了一个java密钥库(JKS)文件:

当然,这会创建一个新的私钥和新证书,但这目前不是问题,因为它是自签名的。我对如何使用我自己的私钥和证书有点困惑。有什么例子吗

然后我简单地更改了keytype和keyfile:

//        String keytype  =  "pkcs12";
        String keytype  =  "JKS";
//        String keyfile  =  appPath + "DanVokt.pfx";
        String keyfile  =  appPath + "danv_keystore.jks";
瞧!它现在又开始工作了

我在J8和J7下编译了它,它在这两种环境下都可以工作


谢谢!

请包含异常的完整stacktraces。它将帮助我们了解发生了什么。此外,请提供用于运行代码的JRE的Java版本/内部版本号。在查找修复程序时,您可以仅为此安装较旧版本的Java。
keytool -genkey -keyalg RSA -keysize 2048 -keystore danv_keystore.jks -alias danv
//        String keytype  =  "pkcs12";
        String keytype  =  "JKS";
//        String keyfile  =  appPath + "DanVokt.pfx";
        String keyfile  =  appPath + "danv_keystore.jks";