6.2.6. 暗号化キーおよび署名キーの提供

概要

標準の WS-SecurityPolicy ポリシーは、セキュリティープロトコル、セキュリティーアルゴリズム、トークンタイプ、認証 要件 など、セキュリティー要件の詳細を指定するように設計されています。ただし、標準のポリシーアサーションは、キーやクレデンシャルなどの関連するセキュリティーデータを指定するためのメカニズムを提供しません。WS-SecurityPolicy は、必要なセキュリティーデータが独自のメカニズムを通じて提供されることを期待しています。Apache CXF では、関連するセキュリティーデータはブループリント XML 設定を通じて提供されます。

暗号化キーおよび署名キーの設定

クライアントのリクエストコンテキストまたはエンドポイントコンテキストでプロパティーを設定することで、アプリケーションの暗号化キーと署名キーを指定できます (「Blueprint 設定への暗号化および署名プロパティーの追加」 を参照)。設定可能なプロパティーは 表6.1「暗号化プロパティーおよび署名プロパティー」 に表示されます。

表6.1 暗号化プロパティーおよび署名プロパティー

プロパティー説明

security.signature.properties

署名キーストアを設定するための WSS4J プロパティーが含まれる WSS4J プロパティーファイル/オブジェクト (復号化にも使用) および Crypto オブジェクト。

security.signature.username

(オプション) 使用する署名キーストア内のキーのユーザー名またはエイリアス。指定のない場合は、プロパティーファイルに設定されたエイリアスが使用されます。これが設定されておらず、キーストアに単一のキーのみが含まれる場合は、そのキーが使用されます。

security.encryption.properties

暗号化キーストアを設定するための WSS4J プロパティーを含む WSS4J プロパティーファイル/オブジェクト (署名の検証にも使用) および Crypto オブジェクト。

security.encryption.username

(オプション) 使用する暗号化キーストア内のキーのユーザー名またはエイリアス。指定のない場合は、プロパティーファイルに設定されたエイリアスが使用されます。これが設定されておらず、キーストアに単一のキーのみが含まれる場合は、そのキーが使用されます。

上記のプロパティーの名前は、使用目的を正確に反映していないため、あまり適切に選択されていません。security.signature.properties で指定されるキーは、実際には署名 および 復号化の両方に使用されます。security.encryption.properties で指定されるキーは、署名の暗号化 および 検証の両方に使用されます。

Blueprint 設定への暗号化および署名プロパティーの追加

Apache CXF アプリケーションで WS-Policy ポリシーを使用する前に、ポリシー機能をデフォルトの CXF バスに追加する必要があります。以下の Blueprint 設定のフラグメントに示されるように、p:policies 要素を CXF バスに追加します。

<beans xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
       xmlns:jaxws="http://cxf.apache.org/jaxws"
       xmlns:cxf="http://cxf.apache.org/core"
       xmlns:p="http://cxf.apache.org/policy" ... >

    <cxf:bus>
        <cxf:features>
            <p:policies/>
            <cxf:logging/>
        </cxf:features>
    </cxf:bus>
    ...
</beans>

以下の例は、署名および暗号化プロパティーを指定されたサービスタイプのプロキシーに追加する方法を示しています (サービス名は jaxws:client 要素の name 属性で指定されます)。プロパティーは WSS4J プロパティーファイルに格納されます。alice.properties には署名キーのプロパティーが含まれ、bob.properties には暗号化キーのプロパティーが含まれます。

<beans ... >
    <jaxws:client name="{http://InteropBaseAddress/interop}MutualCertificate10SignEncrypt_IPingService"
                  createdFromAPI="true">
        <jaxws:properties>
            <entry key="ws-security.signature.properties" value="etc/alice.properties"/>
            <entry key="ws-security.encryption.properties" value="etc/bob.properties"/>
        </jaxws:properties>
    </jaxws:client>
    ...
</beans>

実際、プロパティー名からは明らかではありませんが、これらの各キーは、クライアント側で 2 つの異なる目的に使用されます。

  • alice.properties(security.signature.properties で指定されたキー) は以下のようにクライアント側で使用されます。

    • 送信メッセージに署名するため
    • 受信メッセージの復号化
  • bob.properties(security.encryption.properties で指定されたキー) は以下のようにクライアント側で使用されます。

    • 送信メッセージを暗号化するために使用します。
    • 受信メッセージの署名を検証するため。

これが混乱した場合は、「基本的な署名および暗号化シナリオ」 で詳細の説明を参照してください。

以下の例は、署名および暗号化プロパティーを JAX-WS エンドポイントに追加する方法を示しています。プロパティーファイル bob.properties には署名キーのプロパティーが含まれ、プロパティーファイル alice.properties には暗号化キーのプロパティーが含まれます (これはクライアント設定の逆になります)。

<beans ... >
    <jaxws:endpoint
       name="{http://InteropBaseAddress/interop}MutualCertificate10SignEncrypt_IPingService"
       id="MutualCertificate10SignEncrypt"
       address="http://localhost:9002/MutualCertificate10SignEncrypt"
       serviceName="interop:PingService10"
       endpointName="interop:MutualCertificate10SignEncrypt_IPingService"
       implementor="interop.server.MutualCertificate10SignEncrypt">

        <jaxws:properties>
            <entry key="security.signature.properties" value="etc/bob.properties"/>
            <entry key="security.encryption.properties" value="etc/alice.properties"/>
        </jaxws:properties>

    </jaxws:endpoint>
    ...
</beans>

これらのキーはそれぞれ、サーバー側で 2 つの異なる目的で使用されます。

  • bob.properties(security.signature.properties で指定されたキー) は以下のようにサーバー側で使用されます。

    • 送信メッセージに署名するため
    • 受信メッセージの復号化
  • alice.properties(security.encryption.properties で指定されたキー) は以下のようにサーバー側で使用されます。

    • 送信メッセージを暗号化するために使用します。
    • 受信メッセージの署名を検証するため。

WSS4J プロパティーファイルの定義

Apache CXF は WSS4J プロパティーファイルを使用して、暗号化と署名に必要な公開鍵と秘密鍵をロードします。表6.2「WSS4J Keystore プロパティー」 は、これらのファイルに設定できるプロパティーを説明します。

表6.2 WSS4J Keystore プロパティー

プロパティー説明

org.apache.ws.security. crypto.provider

Crypto インターフェイスの実装を指定します (「WSS4J Crypto インターフェイス」 を参照)。通常、Crypto のデフォルトの WSS4J 実装 org.apache.ws.security.components.crypto.Merlin を指定します。

この表のその他のプロパティーは、Cryptoインターフェイス の Merlin 実装に固有のものです。

org.apache.ws.security. crypto.merlin.keystore.provider

(オプション) 使用する JSSE 鍵ストアプロバイダーの名前。デフォルトのキーストアプロバイダーは Bouncy Castle です。このプロパティーを SunJSSE に設定すると、プロバイダーを Sun の JSSE キーストアプロバイダーに切り替えることができます。

org.apache.ws.security. crypto.merlin.keystore.type

Bouncy Castle キーストアプロバイダーは、JKS および PKCS12 のキーストアをサポートします。さらに、Bouncy Castle は、BKS および UBER の独自のキーストアタイプをサポートしています。

org.apache.ws.security. crypto.merlin.keystore.file

ロードするキーストアファイルの場所を指定します。場所はクラスパスを基準にして指定されます。

org.apache.ws.security. crypto.merlin.keystore.alias

(オプション) キーストアタイプが JKS (Java キーストア) の場合は、エイリアスを指定してキーストアから特定のキーを選択できます。キーストアにキーが 1 つだけ含まれる場合は、エイリアスを指定する必要はありません。

org.apache.ws.security. crypto.merlin.keystore.password

このプロパティーで指定されたパスワードは、キーストアのロックを解除する (キーストアパスワード) と、キーストアに格納されている秘密キーを復号化する (秘密キーパスワード) という 2 つの目的で使用されます。そのため、キーストアのパスワードは秘密鍵のパスワードと同じである必要があります。

たとえば、etc/alice.properties ファイルには、以下のように PKCS#12 ファイル certs/alice.pfx をロードするためのプロパティー設定が含まれています。

org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin

org.apache.ws.security.crypto.merlin.keystore.type=PKCS12
org.apache.ws.security.crypto.merlin.keystore.password=password
org.apache.ws.security.crypto.merlin.keystore.file=certs/alice.pfx

etc/bob.properties ファイルには、以下のように PKCS#12 ファイル certs/bob.pfx をロードするためのプロパティー設定が含まれています。

org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin

org.apache.ws.security.crypto.merlin.keystore.password=password

# for some reason, bouncycastle has issues with bob.pfx
org.apache.ws.security.crypto.merlin.keystore.provider=SunJSSE
org.apache.ws.security.crypto.merlin.keystore.type=PKCS12
org.apache.ws.security.crypto.merlin.keystore.file=certs/bob.pfx

暗号化キーおよび署名キーのプログラミング

暗号化キーと署名キーをロードする別の方法は、表6.3「暗号オブジェクトを指定するプロパティー」 に示すプロパティーを使用して、関連するキーをロードする Crypto オブジェクトを指定することです。これは、 WSS4J Crypto インタフェース org.apache.ws.security.components.crypto.Crypto の独自の実装を提供する必要があります。

表6.3 暗号オブジェクトを指定するプロパティー

プロパティー説明

security.signature.crypto

メッセージの署名および復号化の鍵のロードを担当する Crypto オブジェクトのインスタンスを指定します。

security.encryption.crypto

メッセージの暗号化および署名の検証を行う鍵のロードを担当する Crypto オブジェクトのインスタンスを指定します。

WSS4J Crypto インターフェイス

例6.7「WSS4J Crypto インターフェイス」 は、プログラミングで暗号キーと署名キーを提供する場合は、実装できる Crypto インターフェイスの定義を示しています。詳細は、WSS4J ホームページ を参照してください。

例6.7 WSS4J Crypto インターフェイス

// Java
package org.apache.ws.security.components.crypto;

import org.apache.ws.security.WSSecurityException;

import java.io.InputStream;
import java.math.BigInteger;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;

public interface Crypto {
    X509Certificate loadCertificate(InputStream in)
    throws WSSecurityException;

    X509Certificate[] getX509Certificates(byte[] data, boolean reverse)
    throws WSSecurityException;

    byte[] getCertificateData(boolean reverse, X509Certificate[] certs)
    throws WSSecurityException;

    public PrivateKey getPrivateKey(String alias, String password)
    throws Exception;

    public X509Certificate[] getCertificates(String alias)
    throws WSSecurityException;

    public String getAliasForX509Cert(Certificate cert)
    throws WSSecurityException;

    public String getAliasForX509Cert(String issuer)
    throws WSSecurityException;

    public String getAliasForX509Cert(String issuer, BigInteger serialNumber)
    throws WSSecurityException;

    public String getAliasForX509Cert(byte[] skiBytes)
    throws WSSecurityException;

    public String getDefaultX509Alias();

    public byte[] getSKIBytesFromCert(X509Certificate cert)
    throws WSSecurityException;

    public String getAliasForX509CertThumb(byte[] thumb)
    throws WSSecurityException;

    public KeyStore getKeyStore();

    public CertificateFactory getCertificateFactory()
    throws WSSecurityException;

    public boolean validateCertPath(X509Certificate[] certs)
    throws WSSecurityException;

    public String[] getAliasesForDN(String subjectDN)
    throws WSSecurityException;
}