java - 签名小程序的问题

标签 java javascript jnlp next-generation-plugin signed-applet

我正在开发一个仅在客户端执行加密/解密的应用程序。我正在使用 Spring、jdk 1.6+ 和 eclipse。我开发了一个包含加密代码的小程序,它看起来像:

public void accessToken(){
        try{
            File tmpConfigFile = File.createTempFile("pkcs11", "conf");
            tmpConfigFile.deleteOnExit();
            PrintWriter configWriter = new PrintWriter(new FileOutputStream(tmpConfigFile), true);
            configWriter.println("name=eToken");
            configWriter.println("library=" + "C:\\WINDOWS\\system32\\eTPKCS11.dll");
            configWriter.println("slotListIndex=0");
            configWriter.println("showInfo=true");

            this.pkcs11Provider = new SunPKCS11(tmpConfigFile.getAbsolutePath());
            Security.addProvider(this.pkcs11Provider);

            CallbackHandler cbh = new DialogCallbackHandler();
            KeyStore.Builder ksBuilder = KeyStore.Builder.newInstance("PKCS11", null, new KeyStore.CallbackHandlerProtection(cbh));                     
            KeyStore ks = ksBuilder.getKeyStore();
            ks.load(null, null);            
        }catch(Exception e){
            e.printStackTrace();
        }
    }

我已经创建了 jar 文件并对其进行了签名,当我从 eclipse 在本地计算机上以“在 Java Applet 上运行”的形式运行它时,它运行良好,它也运行良好,当我打开包含此内容的 html 页面时,它会在页面加载时提示输入密码小程序,但是当我单击调用此 accessToken() 小程序方法的复选框时,它会在 Java 控制台上出现错误,例如:

java.lang.SecurityException: Unable to create temporary file
    at java.io.File.checkAndCreate(Unknown Source)
    at java.io.File.createTempFile(Unknown Source)
    at java.io.File.createTempFile(Unknown Source)
    at message.MessageApplet.accessToken(MessageApplet.java:49)
    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 sun.plugin.javascript.JSInvoke.invoke(Unknown Source)
    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 sun.plugin.javascript.JSClassLoader.invoke(Unknown Source)
    at sun.plugin2.liveconnect.JavaClass$MethodInfo.invoke(Unknown Source)
    at sun.plugin2.liveconnect.JavaClass$MemberBundle.invoke(Unknown Source)
    at sun.plugin2.liveconnect.JavaClass.invoke0(Unknown Source)
    at sun.plugin2.liveconnect.JavaClass.invoke(Unknown Source)
    at sun.plugin2.main.client.LiveConnectSupport$PerAppletInfo$DefaultInvocationDelegate.invoke(Unknown Source)
    at sun.plugin2.main.client.LiveConnectSupport$PerAppletInfo$3.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.plugin2.main.client.LiveConnectSupport$PerAppletInfo.doObjectOp(Unknown Source)
    at sun.plugin2.main.client.LiveConnectSupport$PerAppletInfo$LiveConnectWorker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)

我的 html 页面如下所示:

<SCRIPT LANGUAGE="JavaScript">
            function selectedCity() 
            {
                var elem = document.getElementById('cityRb');

                if(elem.checked)
                {
                    document.messageApplet.accessToken();
                }      
            }
        </SCRIPT></HEAD>
    <BODY >
        <b>This is the Applet</b>
     <script src="http://www.java.com/js/deployJava.js"></script>
    <script>
        <!-- applet id can be used to get a reference to the applet object -->
        var attributes = { id:'messageApplet', code:'message.MessageApplet',  width:1, height:1} ;
        var parameters = {jnlp_href: 'message-applet.jnlp'} ;
        deployJava.runApplet(attributes, parameters, '1.6');
    </script>

    <FORM NAME="CityChoice">
        <input type="radio" id="cityRb" name="City" value="Boston" onClick="selectedCity()"> Boston<br>
    </form>
</BODY > 

我的 JNLP 文件如下所示:

<jnlp spec="1.0+" codebase="" href="">
    <information>
        <title>Message Applet</title>
        <vendor>Fountainhead</vendor>
    <offline-allowed/>
    </information>
<update check="background"/>
    <security>
    <all-permissions/>
    </security>
    <resources>
        <!-- Application Resources -->
    <j2se version="1.6+"
              href="http://java.sun.com/products/autodl/j2se"/>
        <jar href="message.jar" main="true" />

    </resources>
    <applet-desc 
         name="Message Applet"
         main-class="message.MessageApplet"
         width="300"
         height="300">
     </applet-desc>
     <update check="background"/>
</jnlp>

所有文件和 jar 都在同一目录中,我的小程序类在消息文件夹中 请帮助我,我被困在这里......

最佳答案

发生这种情况是因为您正在从 javascript 调用小程序的方法。实际上,当您从 javascript 调用任何已签名的小程序的方法时,它的行为与未签名的一样,因为它们都有自己的安全沙箱,并且您必须在该特定沙箱中执行。现在我已经对您的代码进行了如下更改。

final File myFile = (File) AccessController.doPrivileged(new PrivilegedAction() {
                public Object run(){
                    String fileName = System.getProperty("user.home") +
                      System.getProperty("file.separator") +
                      "pkcs11.conf";                    
                    return new File(fileName);
                }});

此 AccessController 允许您在客户端计算机上创建文件。我的英语不好,因此如果有任何错误,请见谅。

关于java - 签名小程序的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10635017/

相关文章:

java - 使用 php 动态创建 JNLP,但存在icedtea web 启动问题

java - 启动由模板签名的 JNLP 时继续获取 "JNLPSigningException [Failed to validate signing of launch file]"

java - 显示具有多个航点的两点之间的路线 Android Here Map Lite Edition

javascript - 我如何在没有表格第一列的情况下打印报告

Java - MaskFormatter

javascript - 去除页面顶部的 scrollspy 效果

javascript - jQuery UI sortable & contenteditable=true 不能一起工作

java - 检查小程序可以使用哪些版本的 Java

java - org.dom4j.DocumentException : Connection refused: connect Nested exception in Hibernate

java - 如何找到抽象方法 hasNext() 的实现?