Java 9のSunPKCS11プロバイダー 質問する

Java 9のSunPKCS11プロバイダー 質問する

Java 8 までは、SunPKCS11 プロバイダーは次のようにロードされていました。

Provider provider = new sun.security.pkcs11.SunPKCS11 (new ByteArrayInputStream (configFile.getBytes ()));
Security.addProvider (provider);

configFileは、構成パラメータを含む文字列です。したがって、アプリケーションが複数の接続されたスマート カードを操作する必要がある場合は、複数のプロバイダーを作成できます。各プロバイダーにアクセスするには、"SunPKCS11-" という名前に続いて、構成で指定した名前を使用します。

Java 8 では、sun.security.pkcs11.SunPKCS11JDK でクラスが削除されました。そのため、以前の呼び出しをリフレクションでプログラムする必要がありました。

Java 9 での PKCS#11 プロバイダーの動作は大きく異なるようです。

  • コンストラクタSunPKCS11が空のものに変更されました。構成は「configure」メソッドによってロードされるため、ディスク上のファイルに存在することが必須であり、ストリームを介して文字列にロードすることはできなくなりました。

  • リフレクションを使用しようとすると、次の警告が表示されます。

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by PruebaTarjeta (file:/C:/temp/pkcs11java9/classes/) to constructor
sun.security.pkcs11.SunPKCS11()
WARNING: Please consider reporting this to the maintainers of PruebaTarjeta
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
  • Java 9では、SunPKCS11プロバイダが自動的に生成され、暗号化プロバイダのリストに含まれます。リストから取得して構成することができます。問題は、リストにロードできるPKCS#11プロバイダは1つだけであることです。Java 9 ドキュメントPKCS#11 プロバイダーは、「SunPKCS11-」の後に構成で指定した名前を付けることで取得できることを示していますが、これは正しくありません。プロバイダーのリストを見ると、「SunPKCS11」だけなので、スマート カードごとに 1 つのプロバイダーを持つことはできません。

他の人にも同じようなことが起きていますか? 解決策はありますか?

ベストアンサー1

javadocを見ていて気づいたのですがconfigure:

指定された構成引数をこのプロバイダインスタンスに適用し、構成されたプロバイダを返します。このプロバイダをインプレースで構成できない場合は、新しいプロバイダーが作成され、返されますしたがって、呼び出し元は常に返されたプロバイダーを使用する必要があります。

これは私にとって、プロトタイプパターンここでは が使用されており、複数のプロバイダーを作成するための新しい制御フローは次のようになります。

Provider prototype = Security.getProvider("SunPKCS11");
Provider provider1 = prototype.configure(...);
Provider provider2 = prototype.configure(...);
...

ファイル名の代わりに引数を直接使用する方法については、ソース コードを調べたところ、次のコードが見つかりましたsun.security.pkcs11.Config

Config(String fn) throws IOException {
    this.filename = fn;
    if (filename.startsWith("--")) {
        // inline config
        String config = filename.substring(2).replace("\\n", "\n");
        reader = new StringReader(config);

の行に注意してくださいfilename.startsWith("--")。このファイル名は の引数から直接取得されますconfigure。つまり、すべき--文字列を で開始し、key=valueでペアを区切る限り、構成引数を文字列として渡すことができます\n(ただし、現時点ではこれをテストすることはできません)。

しかし、この事実はどこにも公に文書化されていないので、変更される可能性があり、またプロバイダによって動作が異なる可能性があります。自己責任でご使用ください。

おすすめ記事