3

クライアント側でのみ暗号化/復号化を実行するアプリケーションを開発しています。私は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アプレットで実行」として実行するとうまく機能し、このアプレットを含む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 は同じディレクトリにあり、アプレット クラスはメッセージ フォルダにあります。助けてください。ここで立ち往生しています...

4

4 に答える 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 を使用すると、クライアント マシンにファイルを作成できます。私は英語が得意ではないので、間違っていたらごめんなさい。

于 2012-08-10T09:52:03.690 に答える
2

(署名されていない) JavaScript から署名されたアプレット内の関数を呼び出すと、即座に署名が壊れます。これは、アプレットが即座にすべての権限を失い、ディスクに何も書き込めなくなることを意味します...

ページの下部にあるこれを見てください: http://docs.oracle.com/javase/tutorial/deployment/applet/security.html

注: JavaScript コードは、署名されていないコードのように扱われます。署名付きアプレットが HTML ページの JavaScript コードからアクセスされると、アプレットはセキュリティ サンドボックス内で実行されます。これは、署名されたアプレットが基本的に署名されていないアプレットのように動作することを意味します。**

そのため、おそらく init() の直後に関数を起動する必要があり、次に liveconnect を介して、「操作完了」を通知するアプレットからページ上の js 関数をコールバックする必要があります...

于 2012-06-01T13:48:34.133 に答える
0

署名されたアプレットが一時ファイルを作成できるようにするには、ポリシーファイルも必要です。
人々がスタックトレースを関連付けることができるように、コードに行番号を追加してください。

私はあなたのコード File.createTempFile("pkcs11", "conf");が投げていると思いますSecurityExceptionmessage.MessageApplet.accessToken(MessageApplet.java:49)スタックトレースから取得したこれを参照してください。

于 2012-05-17T13:57:05.570 に答える
0

データを FIFO (先入れ先出し) オブジェクトに格納するために Javascript を介していつでもアプレットにデータを渡すことができ、アプレットでタイマーを使用して FIFO をチェックし、要求を処理することができます。しかし、失敗/成功コードの値を返すのは簡単ではないと思います...

于 2013-04-05T13:56:16.193 に答える