WS-Security はエンタープライズ WS サービスをセキュアにするために不可欠な機能を提供しますが、パフォーマンスにかなりの犠牲を強いることも珍しくありません。記事「WS-Trust と WS-SecureConversation」では、WS-Security と WS-Trust をベースとする WS-SecureConversation が対称暗号化を使用して、クライアントとサーバーとの間で進行中のメッセージ交換をセキュアにする仕組みを説明しました。今回の記事では、Apache Axis2、Metro、Apache CXF という代表的な 3 つのオープンソースの Java™ Web サービス・スタックで WS-SecureConversation を構成する方法を説明した後、WS-SecureConversation がパフォーマンスに及ぼす影響を調べ、WS-Security が非対称暗号化を使用した場合との比較を行います。
前回の記事で説明したように、WS-SecureConversation メッセージ交換では、クライアントが最初に STS (Security Token Service) エンドポイントに接続して、共有秘密鍵を組み込んだセキュリティー・コンテキストを設定します。それ以降はこの共有秘密鍵に基づいて、ターゲット・サービスとの間で交換するメッセージの暗号化や署名が行われます。セキュリティー・コンテキストを識別するために使われるのは、STS がクライアントに返す SCT (Security Context Token) です。クライアントは、サービスに対するすべてのリクエストにセキュアな対話の一部として SCT を組み込み、サービスはすべてのレスポンスで、その SCT を参照します。
セキュリティー構成は単純な WS-Security の場合と同じく WS-Policy 文書に定義されますが、WS-SecureConversation を使用する場合には、サービスに対するポリシーに 2 つの別個のセキュリティー構成があります。1 つは、STS とのメッセージ交換用のセキュリティー構成、もう 1 つはターゲット・サービス用のセキュリティー構成です。STS セキュリティー構成は、セキュアな対話トークンのポリシー定義の中にネストされます。
この記事では、以下の 3 つのパターンのセキュリティー構成で WS-SecureConversation のパフォーマンスをテストしました。
- 署名のみ
- 暗号化のみ
- 署名と暗号化の両方
いずれのパターンでも同じ STS セキュリティー構成を使用し、クライアントと STS の間で交換される比較的少数のメッセージには、署名を付けるにも、暗号化するにも、非対称鍵を使用しています。リスト 1 は、署名パターンでのパフォーマンス・テストに使用した WS-Policy を編集したものです。STS メッセージ交換に適用されるポリシーは太字で示してあります (この記事に記載するサンプル・コードのソース一式を入手するには、「ダウンロード」を参照してください)。
リスト 1. 署名パターンでのパフォーマンス・テストの WS-Policy
<wsp:Policy wsu:Id="SecureConv" ...>
<wsp:ExactlyOne>
<wsp:All>
<wsap:UsingAddressing xmlns:wsap="http://www.w3.org/2006/05/addressing/wsdl"/>
<sp:SymmetricBinding>
<wsp:Policy>
<sp:ProtectionToken>
<wsp:Policy>
<sp:SecureConversationToken sp:IncludeToken=".../IncludeToken/AlwaysToRecipient">
<wsp:Policy>
<sp:RequireDerivedKeys/>
<sp:BootstrapPolicy>
<wsp:Policy>
<sp:AsymmetricBinding>
<wsp:Policy>
<sp:InitiatorToken>
<wsp:Policy>
<sp:X509Token sp:IncludeToken=".../IncludeToken/AlwaysToRecipient">
<wsp:Policy>
<sp:RequireThumbprintReference/>
</wsp:Policy>
</sp:X509Token>
</wsp:Policy>
</sp:InitiatorToken>
<sp:RecipientToken>
<wsp:Policy>
<sp:X509Token sp:IncludeToken=".../IncludeToken/AlwaysToInitiator">
<wsp:Policy>
<sp:RequireThumbprintReference/>
</wsp:Policy>
</sp:X509Token>
</wsp:Policy>
</sp:RecipientToken>
<sp:AlgorithmSuite>
<wsp:Policy>
<sp:TripleDesRsa15/>
</wsp:Policy>
</sp:AlgorithmSuite>
<sp:Layout>
<wsp:Policy>
<sp:Strict/>
</wsp:Policy>
</sp:Layout>
<sp:IncludeTimestamp/>
<sp:OnlySignEntireHeadersAndBody/>
</wsp:Policy>
</sp:AsymmetricBinding>
<sp:SignedParts>
<sp:Body/>
<sp:Header Name="To" Namespace="http://www.w3.org/2005/08/addressing"/>
...
<sp:Header Name="Action" Namespace="http://www.w3.org/2005/08/addressing"/>
</sp:SignedParts>
<sp:EncryptedParts>
<sp:Body/>
</sp:EncryptedParts>
<sp:Trust13>
<wsp:Policy>
<sp:MustSupportIssuedTokens/>
<sp:RequireClientEntropy/>
<sp:RequireServerEntropy/>
</wsp:Policy>
</sp:Trust13>
</wsp:Policy>
</sp:BootstrapPolicy>
</wsp:Policy>
</sp:SecureConversationToken>
</wsp:Policy>
</sp:ProtectionToken>
<sp:AlgorithmSuite>
<wsp:Policy>
<sp:Basic128Rsa15/>
</wsp:Policy>
</sp:AlgorithmSuite>
<sp:Layout>
<wsp:Policy>
<sp:Strict/>
</wsp:Policy>
</sp:Layout>
</wsp:Policy>
</sp:SymmetricBinding>
<sp:SignedParts>
<sp:Body/>
</sp:SignedParts>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
|
単純な WS-Security での場合と同じく、セキュリティー操作のために追加するランタイム・パラメーター (鍵ストアとパスワードなど) は、それぞれの実装に合わせて定義する必要があります。WS-SecureConversation を使用するには (少なくとも、クライアントと STS との間での対話に) WS-Addressing も必要ですが、WS-Addressing を有効にする方法も、それぞれの実装によって異なります。以降の 3 つのセクションでは、3 種類の Web サービス・スタックのそれぞれについて、セキュリティー・ランタイム・パラメーターを処理する方法、そして WS-Addressing を有効にする方法を説明します。
WS-SecureConversation に応じた Axis2 クライアント構成は、基本的に他のどのタイプの WS-Security を使用する場合とも変わりません。STS とのメッセージ交換で非対称暗号化を使う場合には、クライアントがポリシーの中に <ramp:RampartConfig> 要素を組み込み、そこにセキュリティー・ランタイム・パラメーターを指定する必要があります。Rampart 構成情報は、STS とサービス自体との間で共有されます。
リスト 2 に、この記事のパフォーマンス・テストで使用した Rampart クライアント構成を記載します。この構成は、以前の記事に記載した Axis2 での WS-Security による非対称署名および暗号化の例で使用した構成と同じです。
リスト 2. ポリシーに組み込まれた Axis2/Rampart クライアント構成
<wsp:Policy ...>
<wsp:ExactlyOne>
<wsp:All>
...
<ramp:RampartConfig xmlns:ramp="http://ws.apache.org/rampart/policy">
<ramp:user>clientkey</ramp:user>
<ramp:encryptionUser>serverkey</ramp:encryptionUser>
<ramp:passwordCallbackClass
>com.sosnoski.ws.seismic.adb.PWCBHandler</ramp:passwordCallbackClass>
<ramp:signatureCrypto>
<ramp:crypto provider="org.apache.ws.security.components.crypto.Merlin">
<ramp:property name="org.apache.ws.security.crypto.merlin.keystore.type"
>JKS</ramp:property>
<ramp:property name="org.apache.ws.security.crypto.merlin.file"
>client.keystore</ramp:property>
<ramp:property name="org.apache.ws.security.crypto.merlin.keystore.password"
>nosecret</ramp:property>
</ramp:crypto>
</ramp:signatureCrypto>
<ramp:encryptionCrypto>
<ramp:crypto provider="org.apache.ws.security.components.crypto.Merlin">
<ramp:property name="org.apache.ws.security.crypto.merlin.keystore.type"
>JKS</ramp:property>
<ramp:property name="org.apache.ws.security.crypto.merlin.file"
>client.keystore</ramp:property>
<ramp:property name="org.apache.ws.security.crypto.merlin.keystore.password"
>nosecret</ramp:property>
</ramp:crypto>
</ramp:encryptionCrypto>
</ramp:RampartConfig>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy> |
リスト 3 は、Rampart を構成して WS-Addressing を有効にするための Axis2 クライアント・コードです。この Rampart 構成で使用しているコードは、以前 Axis2 の例で使用したコードと同じですが、今回は太字で示した行が追加されています。この追加の行で addressing モジュールを関与させることによって、WS-Addressing が有効になります。
リスト 3. Axis2 クライアント・コード
Options options = client.getOptions();
options.setProperty(RampartMessageData.KEY_RAMPART_POLICY, policy);
client.engageModule("addressing");
client.engageModule("rampart");
|
Axis2 サーバーの構成は、サービス・アーカイブ (AAR) ファイルに含まれる META-INF/services.xml ファイルに記述されています。Axis2 クライアントの場合と同じく、基本的な Rampart 構成は、前に Axis2 での WS-Security による非対称署名および暗号化の例で使用した構成と同じです。ただし、サービスに対して STS を有効にするために、リスト 4 (編集したバージョン) に太字で示されている内容を追加しなければなりません。
リスト 4. Axis2 サーバー services.xml の追加内容
<serviceGroup>
<service name="seismic-signencr">
...
<module ref="rampart"/>
<module ref="rahas"/>
<module ref="addressing"/>;
<wsp:Policy xmlns:sp=".../ws-sx/ws-securitypolicy/200702"
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:wsu=".../oasis-200401-wss-wssecurity-utility-1.0.xsd"
wsu:Id="SecureConv">
<wsp:ExactlyOne>
<wsp:All>
<wsap:UsingAddressing
xmlns:wsap="http://www.w3.org/2006/05/addressing/wsdl"/>
<sp:SymmetricBinding>
...
</sp:SymmetricBinding>
...
<ramp:RampartConfig xmlns:ramp="http://ws.apache.org/rampart/policy">
<ramp:user>serverkey</ramp:user>
<ramp:encryptionUser>clientkey</ramp:encryptionUser>
<ramp:passwordCallbackClass
>com.sosnoski.ws.seismic.adb.PWCBHandler</ramp:passwordCallbackClass>
<ramp:signatureCrypto>
...
</ramp:signatureCrypto>
<ramp:encryptionCrypto>
...
</ramp:encryptionCrypto>
</ramp:RampartConfig>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
<parameter name="sct-issuer-config">
<sct-issuer-config>
<cryptoProperties>
<crypto provider="org.apache.ws.security.components.crypto.Merlin">
<property name="org.apache.ws.security.crypto.merlin.keystore.type"
>JKS</property>
<property name="org.apache.ws.security.crypto.merlin.file"
>server.keystore</property>
<property name="org.apache.ws.security.crypto.merlin.keystore.password"
>nosecret</property>
</crypto>
</cryptoProperties>
<addRequestedAttachedRef/>
<addRequestedUnattachedRef/>
<!--
Key computation mechanism
1 - Use Request Entropy
2 - Provide Entropy
3 - Use Own Key
-->
<keyComputation>3</keyComputation>
<!--
proofKeyType element is valid only if the keyComputation is set to 3
i.e. Use Own Key
Valid values are: EncryptedKey & BinarySecret
-->
<proofKeyType>BinarySecret</proofKeyType>
</sct-issuer-config>
</parameter>
<parameter name="token-canceler-config">
<token-canceler-config/>
</parameter>
</service>
</serviceGroup> |
リスト 4 で最初に追加されているのは、rahas モジュールと addressing モジュールの参照です。rahas モジュールは単なる基本 Rampart サポートへの追加構成で、サービスに対して STS を有効にするために使用されます。addressing モジュールは、リスト 3 のクライアント・コードでの場合と同じく WS-Addressing サポートを有効にします。
リスト 4 で次に追加されているのは、<parameter name="sct-issuer-config"> 要素とその内容です。この追加部分が、特定の方法で SCT を発行するように STS を構成します。この要素の中に含まれるコメントは、Rampart の例のうちの 1 つからそのまま引用したものです。これらのコメントはこの構成に関する唯一の説明のようですが、残念ながら正確ではありません。Axis2 1.5.1/Rampart 1.5 で実際にテストしたところ、<keyComputation> の値を変更しても STS の動作には何の影響もなく、相変わらず鍵を直接生成してクライアントに返すという結果になりました。この結果は、使用していたポリシーとは一致していません。ポリシーで要件としていたのは、クライアントとサーバーのエントロピーを組み合わせて共有秘密鍵を生成することでした。
CXF を WS-SecureConversation 用に構成するのは、Axis2 での構成方法よりも単純です。クライアント・サイドで必要な作業は、クライアントで使用される cxf.xml ファイルにセキュリティー・ランタイム・パラメーターを追加することだけです。セキュリティー・ランタイム・パラメーターは通常の WS-Security で使用するパラメーターとは名前が異なるだけで (いずれも .sct という接尾辞で終わります)、機能の点では変わりません。リスト 5 に記載するのは、この記事のテストで使用した cxf.xml です。SCT パラメーターは太字で示されています。
リスト 5. CXF クライアントの cxf.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd">
<jaxws:client name="{http://ws.sosnoski.com/seismic/wsdl}seismic" createdFromAPI="true">
<jaxws:properties>
<entry key="ws-security.signature.properties.sct"
value="client-crypto.properties"/>
<entry key="ws-security.signature.username.sct" value="clientkey"/>
<entry key="ws-security.encryption.properties.sct"
value="client-crypto.properties"/>
<entry key="ws-security.encryption.username.sct" value="serverkey"/>
<entry key="ws-security.callback-handler.sct"
value="com.sosnoski.ws.seismic.cxf.ClientCallback"/>
</jaxws:properties>
</jaxws:client>
</beans> |
サーバー・サイドの構成も CXF では簡単な作業ですが、CXF コンテキストの構成を定義する web.xml ファイルと、個々のサービス定義を指定する cxf-servlet.xml ファイルの両方に変更を加える必要があります。まず、web.xml ファイル (リスト 6 を参照) には、cxf-extension-addr.xml 構成を参照する 1 行を追加します。この追加の参照が、クライアントと STS との間でのメッセージ交換に必要な WS-Addressing サポートを CXF 構成に組み込みます (この参照は、リスト 1 のポリシーを使用したクライアントと実際のサービスとの間でのメッセージ交換でも使用されます)。
リスト 6. CXF サーバーの web.xml
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee">
<display-name>CXFLibrary</display-name>
<description>CXF Seismic Service</description>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:META-INF/cxf/cxf.xml
classpath:META-INF/cxf/cxf-extension-soap.xml
classpath:META-INF/cxf/cxf-servlet.xml
classpath:META-INF/cxf/cxf-extension-policy.xml
classpath:META-INF/cxf/cxf-extension-ws-security.xml
classpath:META-INF/cxf/cxf-extension-http.xml
classpath:META-INF/cxf/cxf-extension-addr.xml
</param-value>
</context-param>
<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app> |
リスト 7 に、cxf-servlet.xml 構成ファイルを記載します。ここには、リスト 5 に示されているクライアント用のパラメーターに対応する一連の SCT パラメーター定義が指定されています。
リスト 7. CXF サーバーの cxf-servlet.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xmlns:soap="http://cxf.apache.org/bindings/soap"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd">
<jaxws:endpoint id="Processor"
implementor="com.sosnoski.ws.seismic.cxf.CxfSeismicImpl"
wsdlLocation="WEB-INF/wsdl/seismic.wsdl"
address="/">
<jaxws:properties>
<entry key="ws-security.signature.properties.sct"
value="server-crypto.properties"/>
<entry key="ws-security.signature.username.sct" value="serverkey"/>
<entry key="ws-security.encryption.username.sct" value="useReqSigCert"/>
<entry key="ws-security.callback-handler.sct"
value="com.sosnoski.ws.seismic.cxf.ServerCallback"/>
</jaxws:properties>
</jaxws:endpoint>
</beans> |
Metro では Axis2 と同じく、セキュリティー・ランタイム・パラメーターを渡すためにカスタマイズした内容をセキュリティー・ポリシーに追加します。WS-SecureConversation 用にパラメーターを渡す方法にしても Axis2 と同じく、WS-Security 用にパラメーターを渡す方法と同じです。一方、Axis2 とは異なり、Metro の場合にはサーバーに STS 構成情報を追加する必要がありません。そのため、Metro の構成は Axis2 の構成よりも遥かにシンプルになります。
リスト 8 は、クライアント・サイドの WSDL を編集したバージョンです。Metro セキュリティー・ランタイム・パラメーターは太字で示されています。
リスト 8. パラメーターが追加された Metro クライアントの WSDL
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" ...>
<wsp:Policy xmlns:sp=".../ws-sx/ws-securitypolicy/200702"
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:wsu=".../oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="SecureConv">
<wsp:ExactlyOne>
<wsp:All>
<wsap:UsingAddressing xmlns:wsap="http://www.w3.org/2006/05/addressing/wsdl"/>
<sp:SymmetricBinding>
...
</sp:SymmetricBinding>
...
<wssc:KeyStore alias="clientkey" keypass="clientpass" location="client.keystore"
storepass="nosecret" xmlns:wspp="http://java.sun.com/xml/ns/wsit/policy"
wspp:visibility="private"
xmlns:wssc="http://schemas.sun.com/2006/03/wss/client"/>
<wssc:TrustStore location="client.keystore" peeralias="serverkey"
storepass="nosecret" xmlns:wspp="http://java.sun.com/xml/ns/wsit/policy"
wspp:visibility="private"
xmlns:wssc="http://schemas.sun.com/2006/03/wss/client"/>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
...
<wsdl:service name="SeismicMetro">
<wsdl:port binding="wns:SeismicBinding" name="seismic">
<soap:address location="http://localhost:8080/metro-seismic"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions> |
リスト 9 に、サーバー・サイドの WSDL を記載します。ここでも同じく、ランタイム・パラメーターは太字で示されています。
リスト 9. パラメーターが追加された Metro サーバーの WSDL
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" ...>
<wsp:Policy xmlns:sp=".../ws-sx/ws-securitypolicy/200702"
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:wsu=".../oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="SecureConv">
<wsp:ExactlyOne>
<wsp:All>
<wsap:UsingAddressing xmlns:wsap="http://www.w3.org/2006/05/addressing/wsdl"/>
<sp:SymmetricBinding>
...
</sp:SymmetricBinding>
...
<wsss:KeyStore alias="serverkey"
keypass="com.sosnoski.ws.seismic.metro.KeystoreAccess"
location="server.keystore" storepass="nosecret"
xmlns:wspp="http://java.sun.com/xml/ns/wsit/policy" wspp:visibility="private"
xmlns:wsss="http://schemas.sun.com/2006/03/wss/server"/>
<wsss:TrustStore location="server.keystore" storepass="nosecret"
xmlns:wspp="http://java.sun.com/xml/ns/wsit/policy" wspp:visibility="private"
xmlns:wsss="http://schemas.sun.com/2006/03/wss/server"/>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
...
<wsdl:service name="SeismicMetro">
<wsdl:port binding="wns:SeismicBinding" name="seismic">
<soap:address location="http://localhost:8080/metro-seismic"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions> |
残りの STS 構成は、共通ポリシーからそのまま引き継がれます。
この記事でのパフォーマンスの比較では、以前の記事と同じ地震データ検索サービスをテスト・コードとして使用します。このサービスが使用するデータベースには、1 年間に世界各地で起こった 93,000 件を超える地震のデータが保管されています。サービスに対するリクエストで期間と緯度、経度の範囲を指定すると、指定された範囲内のすべての地震データが返されます。このテスト・アプリケーションの詳細、そしてリクエストとそれに対するレスポンス・メッセージのサンプルについては、「(WS-)Security に伴う高コスト」を参照してください。
以前の記事と同様、パフォーマンス・テストには 2 つのリクエスト・シーケンスを使用します。最初のシーケンスで使用する 1,000 のリクエストでは、地震データベース全体のほんの一部とだけ一致するようにクエリー・パラメーターを調整してあります (1,000 のリクエストに対する一致結果として、816 件の地震データが返されます)。2 番目のシーケンスでは、それよりも多くの件数と一致するように調整した 100 のリクエストを使用します (100 のリクエストに対する一致結果として、176,745 件の地震データが返されます)。この 2 つのリクエスト・シーケンスにより、Web サービス・スタックのパフォーマンス特性の違いが顕著に現れてくることになります。最初のシーケンスによって明らかになるのは、スタックがデータ量の少ないリクエストを処理する場合の速度、そして 2 番目のシーケンスによって明らかになるのは、大量のデータを処理する場合の速度です。それぞれのリクエスト・シーケンスを異なるセキュリティー構成で何度か実行し、構成ごとの最短実行時間だけを結果に残しました。テストしたセキュリティー構成は以下のとおりです。
- セキュリティー未使用 (plain)
- すべてのリクエスト/レスポンスのメッセージ本文に WS-SecureConversation による署名を付加 (sign)
- すべてのリクエスト/レスポンスのメッセージ本文に WS-SecureConversation による暗号化を適用 (encr)
- すべてのリクエスト/レスポンスのメッセージ本文に WS-SecureConversation による署名を付加するとともに暗号化を適用 (signencr)
このテストは Athlon X2 5400+ プロセッサーと 4GB の RAM を搭載したマシンに Mandriva 2009.1 64-bit Linux システムをインストールした環境で、Sun (Oracle) Java 1.6.0_18 32-bit JVM (特定のヒープ・サイズでは、64-bit の JVM より多少優れたパフォーマンスを示します) を使用して実行しました。サーバー・コードは Tomcat 6.0.20 上で実行され、1,024MB のヒープを使用するように構成されています。一方、クライアント・コードが使用するヒープは 512MB です。テストした各 Web サービス・スタックのバージョンは以下のとおりです。
- Rampart 1.5 リリースを適用した Axis2 1.5.1
- Metro 2.0
- CXF 2.1.8
お使いのハードウェアと JVM でこのテストを試すには、「ダウンロード」セクションからサンプル・コードをダウンロードしてください。
図 1 に、少数のレスポンスを返すテストで測定した実行時間を示します。以前行ったテストでは、セキュリティーをまったく使用しないで少数のメッセージを処理する場合、Metro の速度は Axis2 と CXF よりいくらか上回っていました。このパフォーマンスの優位性は、WS-SecureConversation を使用したテストに引き継がれています。全体的に見ると、少数のレスポンスを返すこの一連のテストで、Metro は CXF よりも 25 パーセント速く、Axis2 と比べると約 2 倍の速度となっています (この記事に記載するグラフではいずれも棒の長さが時間の長さを示すため、棒が短ければパフォーマンスに優れていることになります)。
図 1. 少数のレスポンスで測定した実行時間
図 2 に、今度は多数のレスポンスを返すテストで測定した実行時間を示します。このテストでも、3 つのスタックのなかで最も速度に優れているのは Metro ですが、その差は少数のレスポンスを返すテストでの差と比べて遥かに小さくなっています。多数のレスポンスを返すテストでは、WS-SecureConversation を署名のみに使用した場合を除くすべてのセキュリティー構成で、CXF はほぼ Metro と互角です。そして Metro と CXF の両方が、すべての WS-SecureConversation 構成で Axis2 の実行速度を大幅に上回っています (40 パーセント以上)。
図 2. 多数のレスポンスで測定した実行時間
WS-SecureConversation の利点の 1 つとして挙げられるのは、非対称暗号化ではなく対称暗号化を使うことによってもたらされるパフォーマンスの向上です。以降に記載する 3 つのグラフに、このパフォーマンスの向上が実際にどのくらいの数値になるかを示します。これらのグラフでは、それぞれのスタックで、秘密鍵と証明書による WS-Security (非対称暗号化) を使用してテストを実行した場合の時間と、秘密鍵による WS-SecureConversation (対称暗号化) を使用してテストを実行した場合の時間とを比較しています。WS-Security での測定時間は、今回のテストと同一のハードウェア、そしてほぼ同じバージョンの Web サービス・スタック (CXF のバージョンのみが異なります) で行った「CXF のパフォーマンス比較」のテスト結果から引用したものです。ただし、そのときのテストでは暗号化のみの構成を使用した WS-Security のテストの実行時間は測定されていないので (証明書を使用した暗号化のみの構成はサポートされないため)、署名を付けるテストと、署名を付けて暗号化するテストの実行時間だけを比較しています。
図 3 は、Axis2 でのテストの実行時間の比較です。
図 3. Axis2 でのパフォーマンスの比較
図 4 は、Metro でのテストの実行時間の比較です。
図 4. Metro でのパフォーマンスの比較
図 5 は、CXF でのテストの実行時間の比較です。
図 5. CXF でのパフォーマンスの比較
以上の 3 つのグラフには、いずれも同じようなパターンが現れています。署名を付けるだけのテストの結果は、少数のレスポンスを返す場合は WS-SecureConversation の対称暗号化を使用したほうが非対称暗号化を使用する場合に比べ、遥かに高速です。けれどもこの利点は、多数のレスポンスを返す場合には失われてしまいます。署名を付けて暗号化するテストの結果を見ると、WS-SecureConversation の対称暗号化は、レスポンスが少数だと大幅にパフォーマンスが向上しますが (署名を付けるだけのテスト結果よりもさらに大幅な向上)、多数のレスポンスを返す場合には、パフォーマンスの向上は明らかなものの、非対称暗号化との差はかなり小さくなります。
このパターンは何を意味するのでしょうか。メッセージに署名を付与するためには、XML をカノニカル形式に変換するための事前処理を必ず行わなければなりません。この事前処理が完了すると、XML のダイジェストが作成されてハッシュ値が生成されます。実際の署名に最終的に組み込まれるのはハッシュ値であるため、対称暗号化と非対称暗号化とで異なるのは、署名を生成するステップのみということになります。その一方、メッセージを暗号化する場合には、ほとんど変更を加えずに XML のすべてを処理するだけです。
以上のことが、上記の結果を説明しています。つまり、少数のメッセージのうちの多くに、非対称暗号化によって署名を付ける場合、その処理に要する時間の大部分は署名生成のステップに費やされることになります。署名を付けるメッセージ数が多くなれば、カノニカライズとダイジェスト作成のステップに費やされる時間もそれだけ多くなります。対称暗号化は常に非対称暗号化より高速ですが (暗号の強度がほとんど同じ場合)、署名を付けて暗号化する場合には、2 つのステップに費やされる時間によって自然とパフォーマンスの差があまりなくなるというわけです。
WS-Security の非対称暗号化に秘密鍵と証明書のペアを使用する場合に比べ、WS-SecureConversation は進行中のメッセージ交換にかなりのパフォーマンス・ゲインをもたらすことができます (少数のメッセージによるテストでは 2 倍以上のパフォーマンス向上となります)。このパフォーマンスにおける利点は、サービスのクライアントに許可を与えるという処理を行っている場合には、さらに顕著となります。それは、サービスに対する個々のリクエストでいちいち許可のステップを処理するかわりに、STS でまとめて処理できるからです。
WS-SecureConversation を有効に活用するには、比較的短い期間で一連のメッセージ・シーケンスが実行される必要があります。クライアントが 1 回ごとにアクセスするサービスに WS-SecureConversation を使用すると、クライアントと STS との間で頻繁にメッセージ交換が行われることから、実際には大きなオーバーヘッドが追加されることになります。
また、WS-SecureConversation のサポートは、単純な WS-Security ほど相互運用性に優れてはいない可能性も考えられます。この点に関しては、連載の今後の記事で取り上げる予定ですが、来月の記事ではその前に、通常の WS-Security で対称暗号化を使用する場合について説明したいと思います。
| 内容 | ファイル名 | サイズ | ダウンロード形式 |
|---|---|---|---|
| Source code for this article | j-jws16-src.zip | 4.87MB | HTTP |
学ぶために
- Axis2: Axis 2 は、Apache Software Foundation によるオープンソースの Web サービス・スタックです。
- Metro: Metro は、JAXB 2.x および JAX-WS 2.x Java 標準の最新リファレンス実装を組み込んだオープンソースの Web サービス・スタックです。
- CXF: CXF も同じく Apache によるオープンソースの Web サービス・スタックです。
- WSS4J: WSS4J は Apache Software Foundation によるオープンソースの WS-Security 実装です。Axis2 と CXF は両方とも WS-Security の処理に WSS4J を使用しています。
- XWSS: XWSS は、Metro で WS-SecurityPolicy の処理に対応するコンポーネントです。
- 連載「Understanding Web Services specifications」: このチュートリアルの連載では、多数の重要な Web サービス標準を紹介しています。以下のチュートリアルがあります。
- 「Understanding Web Services specifications: Web Services Description Language (WSDL)」(Nicholas Chase 著、developerWorks、2006年7月)
- 「Understanding Web Services specifications: WS-Security」(Nicholas Chase 著、developerWorks、2006年8月)
- 「Understanding Web Services specifications: WS-Policy」(Tyler Anderson 著、developerWorks、2007年2月)
- OASIS Web Services Security (WSS) TC: WS-Security 仕様およびトークン・プロファイルを担当している組織です。これらの標準のすべてのバージョンへのリンクは、このサイトに記載されています。
- W3C Web Services Policy Working Group: このグループが、WS-Policy 仕様を定義しています。
- OASIS Web Services Secure Exchange (WS-SX) TC: WS-SecurityPolicy、WS-SecureConversation、および WS-Trust を担当している組織です。
- developerWorks Java technology ゾーン: Java プログラミングのあらゆる側面を網羅した記事が豊富に用意されています。
議論するために
- My developerWorks コミュニティーに加わってください。ここでは他の developerWorks ユーザーとのつながりを持てる他、開発者が主導するブログ、フォーラム、グループ、ウィキを調べることができます。

Dennis Sosnoski は Java ベースの XML および Web サービスを専門とするコンサルタント兼トレーナーです。専門家としてのソフトウェア開発経験は 30 年以上に渡り、この 10 年間はサーバー・サイドの XML 技術や Java 技術に注力しています。オープンソースのJiBX XML Data Binding フレームワークや、それに関連した JiBX/WS Web サービス・フレームワークの開発リーダーを務め、さらに Apache Axis2 Web サービス・フレームワークのコミッターでもあります。彼は JAX-WS 2.0 および JAXB 2.0 仕様のエキスパート・グループの一員でもありました。