签名小程序存在的问题

3

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

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小程序上运行”时,它可以正常工作。当我打开包含此小程序的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包都在同一个目录下,我的小程序类在message文件夹中。请帮助我,我被卡住了...

当我点击复选框时,它会调用...。通过“checkbox”,您是指cityRb单选框吗?1)W3C对复选框的定义更接近于<input type="checkbox" name="ny">New York。2)如果是这种情况,JS调用会导致立即出现问题。 - Andrew Thompson
1
https://dev59.com/rkjSa4cB1Zd3GeqPCApm - Martin Paljak
4个回答

3
这是因为您从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允许你在客户端机器上创建一个文件。我英语不好,如果有错误请谅解。


2
如果你从JavaScript中调用签名小程序内部的函数,你会立即破坏签名。这意味着该小程序将立即失去所有特权,无法在磁盘上写入任何内容...
请参考此页面底部:http://docs.oracle.com/javase/tutorial/deployment/applet/security.html 注意:JavaScript代码被视为未签名代码。当从HTML页面中的JavaScript代码访问已签名小程序时,该小程序将在安全沙箱中执行。这意味着已签名小程序基本上表现得像未签名小程序。
因此,您可能需要在init()之后立即启动您的函数,然后通过liveconnect从小程序回调您页面上的js函数,通知“操作完成”。

0

您可以通过Javascript将数据传递给小程序,以便将它们存储在FIFO(先进先出)对象中,并在小程序上使用定时器来检查FIFO并处理请求。但我猜返回失败/成功代码值可能不容易...


0

您需要策略文件,以允许签名小程序创建临时文件。
请在您的代码中添加行号,以便人们可以关联堆栈跟踪。

我认为您的代码 File.createTempFile("pkcs11", "conf"); 抛出了 SecurityException。 请看您的堆栈跟踪中提取的 message.MessageApplet.accessToken(MessageApplet.java:49) 消息。


谢谢回复,是的,你说得对,那一行会抛出SecurityException异常。现在我有一个jnlp文件,在其中我已经提到了 <security> <all-permissions/> </security> 但我仍然面临错误。如果是这样,我应该将它放在我的签名jar文件中吗?如果是的话,如何在我的JNLP文件中引用它? - Pravin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接