2014-07-24 70 views
1

我的JavaWS应用程序将运行在一个内部网络中,因此它使用公司自己的证书进行签名,而且SSL证书来自公司的根CA.因此,由于计算机数量巨大,不太可能手动导入每个comupter上的证书。所以,我伸出我的应用程序类,应自动导入证书,这个工作从控制台和IDE但如果申请是由Java Web Start的:(BufferedInputStream在KeyStore.load()后不起作用()

代码

 cf = CertificateFactory.getInstance("X.509"); 

     signCertIn = ClassLoader.class.getResourceAsStream((pack + signCertName + ".cer")); 
     sslCertIn = ClassLoader.class.getResourceAsStream((pack + sslCertName) + ".crt"); 

     File file = new File(new File(System.getProperty("java.home") + SEP + "lib" + SEP + "security"), "cacerts"); 
     javaCertIn = new FileInputStream(file); 

     KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType()); 
     keystore.load(javaCertIn, passphrase); 

     javaCertIn.close(); 

     if (!keystore.containsAlias(signCertName)) { 
      bis = new BufferedInputStream(signCertIn); // <<<<<<< Exception thrown here 
      while (bis.available() > 0) { 
       Certificate cert = cf.generateCertificate(bis); 
       keystore.setCertificateEntry(signCertName, cert); 
      } 
      save = true; 
      signCertIn.close(); 
     } 

     if (!keystore.containsAlias(sslCertName)) { 
      bis = new BufferedInputStream(sslCertIn); 
      while (bis.available() > 0) { 
       Certificate cert = cf.generateCertificate(bis); 
       keystore.setCertificateEntry(sslCertName, cert); 
      } 
      save = true; 
      sslCertIn.close(); 
     } 

     if (save) { 
      OutputStream out = new FileOutputStream(file); 
      keystore.store(out, passphrase); 
      out.close(); 
     } 

javaws的控制台执行输出

java.io.IOException: Stream closed 
at java.io.BufferedInputStream.getInIfOpen(Unknown Source) 
at java.io.BufferedInputStream.available(Unknown Source) 
at at.sviss.util.cert.Certificates.install(Certificates.java:48) 
at at.sviss.Main.main(Main.java:91) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 
at java.lang.reflect.Method.invoke(Unknown Source) 
at com.sun.javaws.Launcher.executeApplication(Unknown Source) 
at com.sun.javaws.Launcher.executeMainClass(Unknown Source) 
at com.sun.javaws.Launcher.doLaunchApp(Unknown Source) 
at com.sun.javaws.Launcher.run(Unknown Source) 
at java.lang.Thread.run(Unknown Source) 
+0

您需要完全权限才能访问文件系统。你的程序有吗?即便如此,我认为java webstart不像独立程序那样使用证书。 –

+0

在启动.jar文件之前,itselfe使用安装目录中的默认“cacerts”密钥库文件进行验证。是的,我的应用程序具有全部权限,在jnlp中定义! – Pali

+1

不要使用available()作为流结束的测试。这不是它的目的。看到Javadoc。 – EJP

回答

1

取而代之的是ClassLoader的:

signCertIn = ClassLoader.class.getResourceAsStream((pack + signCertName + ".cer")); 

使用类itselfe:

signCertIn = Certificates.class.getResourceAsStream((pack + signCertName + ".cer")); 

为我工作...

+0

如果找不到资源,则'Class.getResourceAsStream'返回'null'。 IMO设计不佳。作为引导类的'ClassLoader.class'将会将该调用奇怪地转发给'ClassLoader.getSystemResourceAsStream'。这是对类路径(或扩展类或引导类路径)的资源。这在Java 2之前更有意义。 –

0

Keystore.load()将读取输入流结束流。之后尝试从其中读取任何其他内容是没有意义的。尝试重新开放流,无论您的目的是什么。并不是说这是有道理的。如果keystore.load()没有加载你的证书,我不知道你为什么认为你自己的代码会做得更好。

+0

我只调用一次'keystore.load()',以便读取InputStream javaCertIn以结束并随后关闭。所以我没有在这里看到任何问题?我只是用了我认为错误的课程? – Pali

相关问题