署名付き JNLP ファイルを作成してみる
署名付き JNLP ファイルなるものがあるようです。
・署名付きJNLPファイル
http://docs.oracle.com/javase/jp/8/docs/technotes/guides/deploy/signed_jnlp.html
ドキュメントに書いてますが、厳密には JNLP ファイル自体に署名するわけではなく、こいつを JAR ファイルに JNLP-INF/APPLICATION.JNLP として格納してあげて、その JAR ファイルを署名するという形になるようです。
こんなことする理由は、
・たとえば、ランダム・ライブラリを追加したり、アプリケーション情報を変更したりすることによって、他人がJNLPファイルの内容を確実に変更できないようにします。
・アプリケーション内での任意のJava Virtual Machine (JVM)オプションやJavaシステム・プロパティの使用を許可します。
・他人がHTMLブラウザのアプレットでJARファイルを直接参照できないようにします。
とのことです。
ちょっとだけ試してみます。JNLP ファイル等、アプリケーションは以下のエントリーで書いたものを使用します。
・「Java」Java Web Start (JWS) を使ってみた - プログラム日記
http://a4dosanddos.hatenablog.com/entry/2014/04/10/010947
JNLP ファイルの内容だけ少し変更を加えておきます ( jnlp 要素に version 属性を追加しています )。
■ swingtest.jnlp
<?xml version="1.0" encoding="utf-8"?> <!-- JNLP File for SwingSet2 Demo Application --> <jnlp spec="6.0+" codebase="http://localhost/jws" href="swingtest.jnlp" version="1.0"> <information> <title>swing test</title> <vendor>test</vendor> </information> <security> <all-permissions/> </security> <resources> <j2se version="1.6+"/> <jar href="test.jar"/> </resources> <application-desc main-class="test.Test"/> </jnlp>
ドキュメント踏まえて、swingtest.jnlp からコピーで APPLICATION.JNLP を作成して JNLP-INF ディレクトリに配置、そいつを含む JAR ファイルを作成して署名します。
# cp swingtest.jnlp APPLICATION.JNLP # mkdir JNLP-INF # mv APPLICATION.JNLP JNLP-INF/ # jar cmvf MANIFEST.MF test.jar test/*.class JNLP-INF/ マニフェストが追加されました test/Test$1.classを追加中です(入=594)(出=406)(31%収縮されました) test/Test.classを追加中です(入=885)(出=565)(36%収縮されました) JNLP-INF/を追加中です(入=0)(出=0)(0%格納されました) JNLP-INF/APPLICATION.JNLPを追加中です(入=461)(出=269)(41%収縮されました) # jarsigner -keystore keystore -storepass password test.jar test
■ MANIFEST.MF
Manifest-Version: 1.0 Permissions: all-permissions
■ 上記コマンド実行前のディレクトリ構成
# ls -lR .: 合計 16 -rw-r--r-- 1 root root 74 10月 7 00:30 2015 index.html -rw-r--r-- 1 root root 1254 10月 7 00:30 2015 keystore -rw-r--r-- 1 root root 402 10月 7 00:29 2015 swingtest.jnlp drwxr-xr-x 2 root root 4096 10月 7 00:29 2015 test ./test: 合計 12 -rw-r--r-- 1 root root 594 10月 7 00:29 2015 Test$1.class -rw-r--r-- 1 root root 885 10月 7 00:29 2015 Test.class -rw-r--r-- 1 root root 721 10月 7 00:29 2015 Test.java
あとは「Java コントロールパネルの [署名者の CA] から証明書のインポート ( キーストアからは keytool -exportcert -alias test -keystore keystore -storepass password -file test.cer とかで証明書エクスポートできます )」、「例外サイトリストの追加」を行なえば、JNLP ファイル経由でアプリケーションが実行できるかと思います。
ドキュメントに記載ありますが、実行に使用される JNLP ファイルと JAR ファイルの内の JNLP ファイルは同一である必要があるようです。例えば、実行される側の JNLP ファイルの jnlp 要素の version 属性とかを変更してみると、「JNLPSigningException[起動ファイルの署名の検証に失敗しました。署名済のバージョンとダウンロードされたバージョンとが一致しません。]」という例外が発生してアプリケーションが実行できません。
そのアプリケーションを実行するには、使用されるJNLPファイルと、署名付きJAR内のJNLPファイルが同一である必要があります。
JNLPSigningException[起動ファイルの署名の検証に失敗しました。署名済のバージョンとダウンロードされたバージョンとが一致しません。] at com.sun.javaws.jnl.LaunchDesc.checkSigning(Unknown Source) at com.sun.javaws.security.JNLPSignedResourcesHelper.checkSignedLaunchDescHelper(Unknown Source) at com.sun.javaws.security.JNLPSignedResourcesHelper.checkSignedLaunchDesc(Unknown Source) at com.sun.javaws.security.JNLPSignedResourcesHelper.checkSignedLaunchDesc(Unknown Source) at com.sun.javaws.Launcher.prepareResources(Unknown Source) at com.sun.javaws.Launcher.prepareAllResources(Unknown Source) at com.sun.javaws.Launcher.prepareToLaunch(Unknown Source) at com.sun.javaws.Launcher.prepareToLaunch(Unknown Source) at com.sun.javaws.Launcher.launch(Unknown Source) at com.sun.javaws.Main.launchApp(Unknown Source) at com.sun.javaws.Main.continueInSecureThread(Unknown Source) at com.sun.javaws.Main.access$000(Unknown Source) at com.sun.javaws.Main$1.run(Unknown Source) at java.lang.Thread.run(Unknown Source)
同じ内容のファイルが2つ存在するってなんとなく無駄気がしますね・・・
以上になります。
[ 環境情報 ]
CentOS 6.2
Java SE 8
Apache HTTP Server 2.2.15
Windows 7 SP1
Java SE 8 Update 45
Internet Explorer 11