【问题标题】:DerInputStream.getLength(): lengthTag=66DerInputStream.getLength(): lengthTag=66
【发布时间】:2016-10-22 17:12:07
【问题描述】:

我在尝试加载证书时遇到以下问题:

> java.io.IOException: DerInputStream.getLength(): lengthTag=66, too big.
|   at sun.security.util.DerInputStream.getLength(DerInputStream.java:561)
|   at sun.security.util.DerValue.init(DerValue.java:365)
|   at sun.security.util.DerValue.<init>(DerValue.java:320)
|   at sun.security.pkcs12.PKCS12KeyStore.engineLoad(PKCS12KeyStore.java:1914)
|   at java.security.KeyStore.load(KeyStore.java:1445)
|   at com.sequenceiq.cloudbreak.cloud.wap.client.WapClient.getFactory(WapClient.java:61)
|   at com.sequenceiq.cloudbreak.cloud.wap.client.WapClient.checkConnect(WapClient.java:80)
|   at com.sequenceiq.cloudbreak.cloud.wap.WapCredentialConnector.verify(WapCredentialConnector.java:53)
|   at com.sequenceiq.cloudbreak.cloud.handler.CredentialVerificationHandler.accept(CredentialVerificationHandler.java:43)
|   at com.sequenceiq.cloudbreak.cloud.handler.CredentialVerificationHandler.accept(CredentialVerificationHandler.java:20)
|   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
|   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
|   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
|   at java.lang.reflect.Method.invoke(Method.java:498)
|   at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:302)
|   at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
|   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
|   at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:52)
|   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
|   at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
|   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
|   at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208)
|   at com.sun.proxy.$Proxy201.accept(Unknown Source)
|   at reactor.bus.EventBus$3.accept(EventBus.java:317)
|   at reactor.bus.EventBus$3.accept(EventBus.java:310)
|   at reactor.bus.routing.ConsumerFilteringRouter.route(ConsumerFilteringRouter.java:72)
|2016-06-07 19:56:59,465 [reactorDispatcher-17] accept:56 [34mINFO [0;39m c.s.c.c.h.CredentialVerificationHandler - [owner:c90f9d2e-587f-4af6-a3a8-f1d321caa3a1] [type:springLog] [id:null] [name:debug2] Credential verification successfully finished
|   at reactor.bus.routing.TraceableDelegatingRouter.route(TraceableDelegatingRouter.java:51)
|   at reactor.bus.EventBus.accept(EventBus.java:591)
|   at reactor.bus.EventBus.accept(EventBus.java:63)
|   at reactor.core.dispatch.AbstractLifecycleDispatcher.route(AbstractLifecycleDispatcher.java:160)
web01#3|2016-06-07 19:56:59,466 [http-nio-9091-exec-4] init:51 [34mINFO [0;39m c.s.c.s.s.c.a.ServiceProviderCredentialAdapter - [owner:c90f9d2e-587f-4af6-a3a8-f1d321caa3a1] [type:springLog] [id:] [name:] Result: CloudPlatformResult{status=OK, statusReason='null', errorDetails=null, request=CloudPlatformRequest{cloudContext=CloudContext{id=null, name='debug2', platform='StringType{value='WAP'}', owner='c90f9d2e-587f-4af6-a3a8-f1d321caa3a1'}, cloudCredential=com.sequenceiq.cloudbreak.cloud.model.CloudCredential@4bd64260}}
|   at reactor.core.dispatch.MultiThreadDispatcher$MultiThreadTask.run(MultiThreadDispatcher.java:74)
|   at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
|   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
|   at java.lang.Thread.run(Thread.java:745)

这里是代码示例:

          keyInput = new FileInputStream(pKeyFile);
          keyStore.load(keyInput, pKeyPassword.toCharArray());
          keyInput.close();

请注意,在加载之前,我将服务器收到的证书写入一个新文件中:

        File file = new File(name);
        try(FileWriter fw = new FileWriter(file)){
            fw.write(certificate);
        }catch(IOException e){
            LOGGER.debug("Writer issue",e);
        }

我已经尝试在写入文件后读取它并且它可以工作。所以我很确定这不是 InputStream 问题。

证书是一个 pkcs12 文件。 难道是我无法加载我刚刚写在新文件中的证书?

【问题讨论】:

  • 写入文件后是调用 fw.flush() 还是 fw.close()?
  • 是的,它隐藏在资源docs.oracle.com/javase/7/docs/technotes/guides/language/…的尝试中
  • 好的,我认为需要更多关于您正在保存和加载的文件的上下文。 keystore.load() 需要 JKS 格式的输入文件,这是您要加载的内容吗?
  • 我写的文件是pkcs12文件。然后我尝试使用 keyStore 加载它作为证书加载。请注意,密钥库使用 pkcs12 格式,我尝试使用我机器中已经存在的另一个文件,它可以工作
  • 您只能从 JKS 文件加载密钥库。通常使用 JDK 提供的 keytool 应用程序将 pkcs12 文件导入密钥库。例如:webfarmr.eu/2010/04/…

标签: java certificate keystore pkcs12


【解决方案1】:

PKCS#12编码为DER格式,DER格式为二进制。

您正在使用(来自 javadoc)的 FileReader

编写字符文件的便利类。

继承自 OutputStreamWriter

OutputStreamWriter 是从字符流到字节流的桥梁:写入其中的字符使用指定的字符集编码为字节。

因此

  1. 将二进制转换为字符时遇到编码问题
  2. 您收到的文件并不是真正的二进制格式。它可能在 Base64 中

在这两种情况下,使用FileOutputStream.writeFiles.write 来存储文件,如果您的“证书”变量是字符串,请先将其转换为二进制

File file = new File(name);
FileOutputStream fout = new FileOutputStream(file);
fout.write (data);

Files.write(Paths.get("name"), data);

【讨论】:

  • 我改为:try(FileOutputStream fw = new FileOutputStream(file)){ fw.write(certificate.getBytes()); }catch(IOException e){ LOGGER.debug("Writer 问题",e); } 我得到了和以前一样的错误。
  • “证书”是什么变量?你是怎么读的?问题可能就在那里。你应该有一个byte[] 而不是String 你检查过数据是否真的是二进制格式吗?
  • 我认为它是二进制的:\Q?ÆØ?zv$ÁdùQC¥¹ºÃH(打印时看起来像那样)。证书是一个字符串。
  • 它是二进制的,所以它不应该在字符串中。请将保存文件的扩展名设置为 .p12 并双击您的计算机以查看操作系统是否可以打开它。如果您不是 windows 用户,请将数据编码为 base64 并将其插入此页面:lapo.it/asn1js。如果操作系统打开文件或页面解码内容,则文件正常,否则文件保存错误,或者不是 pcks12,或者您以某种方式添加了一些额外字符
  • 我可以用 Windows 打开它。问题是我将它作为字符串从客户端传递到服务器端。所以这就是为什么我有一个字符串。您认为我应该在客户端做一些事情以将其作为 byte[] 传递吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-03-22
  • 1970-01-01
  • 2019-05-15
  • 2014-06-01
  • 2011-11-15
  • 2017-08-29
  • 2014-01-28
相关资源
最近更新 更多