web-dev-qa-db-ja.com

SunPKCS11プロバイダーJava 9

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

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

configFileは、構成パラメーターを含むストリングです。したがって、アプリケーションが複数の接続されたスマートカードで動作する必要がある場合、複数のプロバイダーが作成される可能性があります。各プロバイダーにアクセスするために使用した名前は、「SunPKCS11-」であり、その後に構成で指定した名前が続きました。

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

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のドキュメント は、「SunPKCS11-」の後に構成で指定した名前が続くPKCS#11プロバイダーを取得できることを示していますが、これは正しくありません。プロバイダーのリストでは、唯一の「SunPKCS11」なので、スマートカードごとに1つのプロバイダーを持つことはできません。

これは他の人にも起こりますか?解決策はありますか?

19
Pepe Gutiérrez

configure のjavadocを見ていることに気づきました:

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

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

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で区切る限り、構成引数を文字列として渡すことができます。 (ただし、現在これをテストすることはできません)。

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

15
Jorn Vernee

問題は、リストにロードできるPKCS#11プロバイダーは1つだけであることです。

あなたの問題の解決策は doc自体にリンクされています。 で定義されているようです

PKCS#11の実装ごとに複数のスロットを使用したり、複数のPKCS#11の実装を使用したりするには、適切な構成ファイルを使用して、それぞれのインストールを繰り返します。このは、各PKCS#11実装のスロットごとにSun PKCS#11プロバイダーインスタンスを生成します。

attribute=valueという形式のサンプル構成は次のようになります。

name = FooAccelerator
library = /opt/foo/lib/libpkcs11.so
slot = 1

さらに、同じリンクのPKCS#11プロバイダー構成ファイルのAttributesを使用して、異なるスロットIDとlistIndexおよび異なる属性を持つ複数のプロバイダーを構成できます。

0
Naman