PKCS#12:DerInputStream.getLength()exception

我使用keytool命令生成证书:

keytool -genkeypair -alias myRSAKey -keyalg RSA -keysize 1024 -keystore test.p12 -storepass test -storetype pkcs12 

然后,如果我尝试使用java安全API加载它,在将文件作为byte []获取后:

 KeyStore ks = KeyStore.getInstance("PKCS12"); try{ ks.load(new ByteArrayInputStream(data), "test".toCharArray()) } catch (Exception e){ ... } 

我得到一个DerInputStream.getLength():lengthTag = 127,太大的exception。

哪里不对?

我有这个问题,我搜索谷歌的深度,但仍然找不到答案。 经过几天与可怕的高质量遗留代码作斗争,我发现导致此错误的原因。

 KeyStore.load(InputStream is, String pass); 

这个方法接受一个I​​nputStream,如果这个InputStream有任何问题,抛出这个exception,我遇到了一些问题:

  • InputStream指向错误/空白/刚刚创建的文件
  • InputStream已经打开或其他东西正在保存资源
  • InputStream 已经被使用和读取 ,因此InputStream的下一个字节的位置就是它的结束

最后一个是我的问题的责任。 代码是从证书创建一个InputStream,并在两个KeyStore.load()调用中继续使用它,第一个成功,第二个总是让我犯这个错误。

您创建的证书可能在最后有一个额外的字符,被误解为另一个证书。 最后使用一个或多个空行。

请参阅: Java证书解析

对于有类似问题的其他人:

 "keystore load: DerInputStream.getLength(): lengthTag=109, too big." 

对我来说,解决方案是删除参数: -storetype pkcs12因为标准类型是jks

在代码中指定证书类型,例如:

 System.setProperty("javax.net.ssl.trustStoreType", "jks"); System.setProperty("javax.net.ssl.keyStoreType", "pkcs12"); 

你做错了什么。
我尝试了你的命令然后加载了p12就好了。
以下代码有效:

  FileInputStream fin = new FileInputStream("..\\test.p12"); KeyStore ks = KeyStore.getInstance("PKCS12"); ks.load(fin, "123456".toCharArray()); System.out.println(ks.getCertificate("myrsakey")); 

我想知道你是否把命令放在你从keytool得到一个错误,密码必须至少6个字符。
你没有得到那个错误? 你使用的是哪个版本的java?
注意:如果您需要创建证书,您还可以查看此工具。
http://sourceforge.net/projects/certhelper/

我遇到过同样的问题。

我的解决方案是在下面的行中用jceks替换PKCS12,因为我显然使用了错误的类型。

 KeyStore clientStore = KeyStore.getInstance("PKCS12"); 

这件事发生在我身上,因为我在我的Windows 10机器上本地复制并粘贴了.p12文件。 不知道这是什么/为什么这是一个问题,但当我克隆一个具有.p12文件的项目并将我的代码指向它们时,文件可以工作。 但是,将Windows文件资源管理器中的文件复制并粘贴到硬盘驱动器上的其他位置会导致此错误!