2012-05-17 78 views
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 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都在同一個目錄,我的小程序類是在短信文件夾 請幫幫我,我被困在這裏...

+0

*「當我點擊複選框,調用..」*通過'複選框'DYM'cityRb'收音機? 1)W3C [複選框的定義](http://www.w3.org/wiki/HTML/Elements/input/checkbox)更多地沿着紐約2)如果是這樣的話,那麼JS調用就會造成直接的問題。 –

+1

http://stackoverflow.com/questions/1006674/how-can-i-get-a-signed-java-applet-to-perform-privileged-operations-when-called –

回答

3

發生這種情況是因爲您從您的JavaScript調用您的小程序的方法。實際上,當你從JavaScript調用任何簽名的applet的方法時,它的行爲如同未簽名,因爲它們都擁有自己的安全沙箱,並且你必須在特定的沙箱中執行。現在我已經對你的代碼進行了如下修改。

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允許您在客戶機上創建文件。我英語不好,因此如果有任何錯誤,那麼抱歉。

+1

感謝Balasaheb的工作。我們的名字是一樣的... – Pravin

0

您需要該策略文件也允許簽名的applet創建臨時文件。
請將行號添加到您的代碼中,以便人們可以關聯堆棧跟蹤。

我認爲你的代碼File.createTempFile("pkcs11", "conf");正在投擲SecurityException。 請參閱此message.MessageApplet.accessToken(MessageApplet.java:49)取自您的堆棧跟蹤。

+0

感謝您的重播,是的,你是對的行引發SecurityException。現在我有我提到的jnlp文件 但仍然面臨錯誤。我應該把它放在我簽名的jar文件中,如果是的話,如何將它引用到我的JNLP文件中? – Pravin

2

如果您從(無符號)javascript調用一個函數INSIDE簽名的小程序,您將立即中斷簽名。這意味着,小程序即刻失去所有的特權時,將不能夠寫在磁盤上的任何東西......

看一看這一點,在頁面底部:http://docs.oracle.com/javase/tutorial/deployment/applet/security.html

注:JavaScript代碼被視爲未簽名的代碼。當從HTML頁面中的JavaScript代碼訪問已簽署的 小程序時,該小程序將在安全沙箱中執行 。這意味着簽署 applet的行爲基本上喜歡的簽名Applet。**

所以你可能在init(後立即啓動您的功能),然後,thorugh LiveConnect的,回撥JS功能在網頁上從小程序通知「操作完成」...

0

您可以隨時通過Javascript將數據提供給applet,以將它們存儲在FIFO(先進先出)對象中,並使用applet上的計時器來檢查FIFO並處理請求。但我想返回失敗/成功代碼值並不容易...