SOAP 本文の暗号化
このトピックでは、InterSystems IRIS Web サービスおよび Web クライアントによって送信される SOAP メッセージの本文を暗号化する方法について説明します。
"セキュリティ・ヘッダ要素の暗号化" のトピックおよび "暗号化および署名への派生キー・トークンの使用" のトピックでは、セキュリティ・ヘッダ要素を暗号化する方法および SOAP 本文を暗号化する他の方法について説明しています。
暗号化の概要
SOAP メッセージの暗号化に対する InterSystems IRIS サポートは、WS-Security 1.1 を基盤としています。また、WS-Security は、XML 暗号化仕様に従います。後者の仕様に従って、XML ドキュメントを暗号化する方法は、以下のとおりです。
-
一時的に使用する対称鍵を生成します。
-
これを使用して、ドキュメント (または、ドキュメントの選択部分) を暗号化します。
ドキュメントのこの部分を、暗号化されたコンテンツを含む <EncryptedData> 要素に置き換えます。
-
ドキュメントの送信先エンティティの公開鍵を使用して、対称鍵を暗号化します。
公開鍵は、そのエンティティからの要求メッセージに含まれている X.509 証明書から取得できます。または、事前に取得することができます。
-
暗号化された対称鍵を、同じドキュメントの <EncryptedKey> 要素内に含めます。<EncryptedKey> 要素は、この要素の解読に使用する鍵を受信者が判別できる情報を直接または間接的に提供します。
この情報は、<EncryptedKey> 要素内に含めることができます。または、<EncryptedKey> 要素は、X.509 証明書または署名済みの SAML アサーションを格納しているバイナリ・セキュリティ・トークンへの直接参照を含めることができます。後者の場合、<Signature> 要素を追加する前にセキュリティ・トークンをメッセージに追加する必要があります。
ドキュメントには、ドキュメントのさまざまな暗号化部分に適用可能な複数の <EncryptedKey> 要素を含めることができます。
別のトピックで、SOAP メッセージの各部分を暗号化するその他の方法について説明します。メッセージ自体の詳細はさまざまですが、一般的なプロセスは同じで、XML 暗号化仕様に従います。つまり、対称鍵の生成および使用、対称鍵の暗号化、暗号化された対称鍵のメッセージへの組み込みを行います。
SOAP 本文の暗号化
SOAP メッセージの本文を暗号化するには、次に説明する基本的な手順を使用するか、またはサブセクションで説明するバリエーションを使用します。まず、次の図にプロセスを示します。
詳細なプロセスは以下のとおりです。
-
必要に応じて、%soap.inc インクルード・ファイルを組み込みます。このファイルには、使用する可能性のあるマクロが定義されています。
-
SOAP メッセージを受信するエンティティの公開鍵を含む資格情報セットを取得します。一般的には、受信した着信メッセージから取得します。"プログラムによる資格情報セットの取得" を参照してください。
例 :
set credset=..SecurityIn.Signature.X509Credentials
"プログラムによる資格情報セットの取得" の説明に従って、返されたオブジェクトのタイプが %SYS.X509CredentialsOpens in a new tab のインスタンスかどうか確認します。
-
その資格情報セットに関連付けられている証明書を含むバイナリ・セキュリティ・トークンを作成します。これには、%SOAP.Security.BinarySecurityTokenOpens in a new tab の CreateX509Token() クラス・メソッドを呼び出します。以下はその例です。
set bst=##class(%SOAP.Security.BinarySecurityToken).CreateX509Token(credset)
このメソッドは、<BinarySecurityToken> ヘッダ要素を表す %SOAP.Security.BinarySecurityTokenOpens in a new tab のインスタンスを返します。
-
WS-Security ヘッダ要素にこのトークンを追加します。そのためには、Web クライアントまたは Web サービスの SecurityOut プロパティの AddSecurityElement() メソッドを呼び出します。このメソッドの引数には、作成したトークンを使用します。以下はその例です。
do ..SecurityOut.AddSecurityElement(bst)
-
バイナリ・セキュリティ・トークンに基づいて、暗号化キーを作成します。これには、%XML.Security.EncryptedKeyOpens in a new tab の CreateX509() クラス・メソッドを呼び出します。以下はその例です。
set enckey=##class(%XML.Security.EncryptedKey).CreateX509(bst)
このメソッドは、対称鍵を生成し、これを使用して SOAP 本文を暗号化し、<EncryptedKey> ヘッダ要素を表す %XML.Security.EncryptedKeyOpens in a new tab のインスタンスを返します。このヘッダ要素には、指定されたバイナリ・セキュリティ・トークン内にある公開鍵で暗号化された対称鍵が含まれます。
-
必要に応じて、別のアルゴリズムを使用するように暗号化キーのインスタンスを変更します。"ブロック暗号化アルゴリズムの指定" および "鍵転送アルゴリズムの指定" を参照してください。
-
WS-Security ヘッダ要素に <EncryptedKey> 要素を追加します。そのためには、Web クライアントまたは Web サービスの SecurityOut プロパティの AddSecurityElement() メソッドを呼び出します。追加する要素について、%XML.Security.EncryptedKeyOpens in a new tab のインスタンスを指定します。
以下はその例です。
do ..SecurityOut.AddSecurityElement(enckey)
この手順では、<Body> 要素の子として <EncryptedData> 要素も追加します。
-
SOAP メッセージを送信します。SOAP 本文は暗号化され、WS-Security ヘッダはメッセージに含まれます。
WS-Security ヘッダには、<BinarySecurityToken> 要素および <EncryptedKey> 要素が含まれます。
"セキュリティ・ヘッダ要素の追加" の一般的な手順を参照してください。
バリエーション :証明書を指定する情報の使用
<BinarySecurityToken> には、シリアル化された Base 64 のエンコード形式の証明書が含まれています。このトークンを省略し、代わりに証明書を指定する情報を使用できます。受信者は、この情報を使用して、適切な場所から証明書を取得します。そのためには、前述の手順を使用しますが、以下の変更点があります。
-
手順 3 と 4 をスキップします。つまり、<BinarySecurityToken> を追加しないでください。
-
手順 5 (暗号化キーの作成) で、CreateX509() の最初の引数として手順 1 の資格情報セットを使用します (バイナリ・セキュリティ・トークンは使用しません)。以下はその例です。
set enckey=##class(%XML.Security.EncryptedKey).CreateX509(credset,,referenceOption)
3 番目の引数 (referenceOption) では、<Signature> 要素が証明書を使用する方法を指定できます。
(このバリエーションで実行しているように) 最初の引数として資格情報セットを指定する場合、referenceOption の既定値は $$$SOAPWSReferenceThumbprint です。必要に応じて、このサブセクションの説明に従って、値を指定します。$$$SOAPWSReferenceDirect 以外の任意の値を使用できます。
X.509 証明書の参照オプション
"WS-Security ヘッダの概要" のセクションでは、証明書が SOAP メッセージで使用される 1 つの方法を示しています。そこでの例では、デジタル・シグニチャは、以下の 2 つのヘッダ要素から構成されています。
-
シリアル化された Base 64 のエンコード形式の証明書を保持する <BinarySecurityToken>。
-
シグニチャを保持し、バイナリ・セキュリティ・トークンへの直接参照を含む <Signature> 要素。
参照の形式は、この他にも考えられます。例えば、<Signature> は、代わりに証明書のサムプリントを含むことができ、この場合、メッセージに <BinarySecurityToken> は不要です。
暗号化キー、デジタル・シグニチャ、または SAML アサーションを作成する場合、referenceOption 引数を指定することにより、新しく作成された要素が、資格情報に含まれている証明書 (つまり、キー・マテリアル) を使用する方法を制御できます。
参考として、この引数は、以下のいずれかの値を持つことができます。これらの値は、%soap.inc インクルード・ファイルで定義されているマクロです。
要素にバイナリ・セキュリティ・トークンへの直接参照が組み込まれます。具体的には、<KeyInfo> 要素は、URI 属性が <BinarySecurityToken> に対するローカル参照である <Reference> 要素を下位に持つ <SecurityTokenReference> 下位要素を使用して作成されます。このオプションを使用するには、必ず WS-Security ヘッダにセキュリティ・トークンも追加しなければなりません。詳細は、関連するセクションを参照してください。
この要素には、X.509 証明書の SHA-1 サムプリントが組み込まれます。
この要素には、X.509 証明書の SubjectKeyIdentifier が組み込まれます。
この要素には、<X509IssuerSerial> 要素を格納する <X509Data> の子を持つ <SecurityTokenReference> の子が指定された <KeyInfo> 要素が組み込まれます。
この要素には、<X509Certificate> 要素を格納する <X509Data> の子を持つ <KeyInfo> 要素が組み込まれます。WS-Security 仕様では、これを <Signature> 要素と <EncryptedKey> 要素に使用することは推奨されていませんが、<Assertion> 要素では使用できます。
この要素には、<X509IssuerSerial> 要素を格納する <X509Data> の子を持つ <KeyInfo> 要素が組み込まれます。WS-Security 仕様では、これを <Signature> 要素と <EncryptedKey> 要素に使用することは推奨されていませんが、<Assertion> 要素では使用できます。
この要素には、<X509SKI> 要素を格納する <X509Data> の子を持つ <KeyInfo> 要素が組み込まれます。WS-Security 仕様では、これを <Signature> 要素と <EncryptedKey> 要素に使用することは推奨されていませんが、<Assertion> 要素では使用できます。
この要素には、<X509SubjectName> 要素を格納する <X509Data> の子を持つ <KeyInfo> 要素が組み込まれます。WS-Security 仕様では、これを <Signature> 要素と <EncryptedKey> 要素に使用することは推奨されていませんが、<Assertion> 要素では使用できます。
この要素には、<RSAKeyValue> 要素を格納する <KeyValue> の子を持つ <KeyInfo> 要素が組み込まれます。WS-Security 仕様では、これを <Signature> 要素と <EncryptedKey> 要素に使用することは推奨されていませんが、<Assertion> 要素では使用できます。
バリエーション :署名済みの SAML アサーションの使用
署名済みの SAML アサーションの証明書に格納されている公開鍵を使用して暗号化するには、以下の手順を実行します。
-
前述の手順の手順 1–4 をスキップします。
-
Holder-of-key メソッドを使用する <SubjectConfirmation> 要素を使用して、署名済みの SAML アサーションを作成します。"SAML トークンの作成と追加" を参照してください。
-
<EncryptedKey> 要素を作成します。そのためには、CreateX509() クラス・メソッドの最初の引数として署名済みの SAML アサーションを使用します。以下はその例です。
set enckey=##class(%XML.Security.EncryptedKey).CreateX509(signedassertion)
-
前述の手順の手順 5 から続行します。
メッセージの暗号化の例
この例では、Web クライアント (ここでは示されていません) は署名済みの要求メッセージを送信し、Web サービスは暗号化された応答を送信します。
Web サービスは、クライアント証明書の要求メッセージのシグニチャから公開鍵を取得し、それを使用して、その応答内に <EncryptedKey> 要素を追加します。この応答は暗号化されます。<EncryptedKey> 要素は、クライアントの公開鍵で暗号化され、この要素には、応答メッセージ本文を暗号化するのに使用される対称鍵が含まれます。
Web サービスは、次のとおりです。
Class XMLEncr.DivideWS Extends %SOAP.WebService
{
Parameter SECURITYIN = "REQUIRE";
Parameter SERVICENAME = "XMLEncryptionDemo";
Parameter NAMESPACE = "http://www.myapp.org";
Method Divide(arg1 As %Numeric = 2, arg2 As %Numeric = 8) As %Numeric [ WebMethod ]
{
Do ..EncryptBody()
Try {
Set ans=arg1 / arg2
} Catch {
Do ..ApplicationError("division error")
}
Quit ans
}
Method EncryptBody()
{
//Retrieve X.509 certificate from the signature of the inbound request
Set clientsig = ..SecurityIn.Signature
Set clientcred = clientsig.X509Credentials
set bst=##class(%SOAP.Security.BinarySecurityToken).CreateX509Token(clientcred)
do ..SecurityOut.AddSecurityElement(bst)
//generate a symmetric key, encrypt that with the public key of
//the certificate contained in the token, and create an
//<EncryptedKey> element with a direct reference to the token (default)
Set enc=##class(%XML.Security.EncryptedKey).CreateX509(bst)
//add the <EncryptedKey> element to the security header
Do ..SecurityOut.AddSecurityElement(enc)
}
/// Create our own method to produce application specific SOAP faults.
Method ApplicationError(detail As %String)
{
//details omitted
}
}
このサービスは、次のような応答メッセージを送信します。
<?xml version="1.0" encoding="UTF-8" ?>
<SOAP-ENV:Envelope [parts omitted]>
<SOAP-ENV:Header>
<Security xmlns="[parts omitted]oasis-200401-wss-wssecurity-secext-1.0.xsd">
<BinarySecurityToken wsu:Id="SecurityToken-4EC1997A-AD6B-48E3-9E91-8D50C8EA3B53"
EncodingType="[parts omitted]#Base64Binary"
ValueType="[parts omitted]#X509v3">
MIICnDCCAYQ[parts omitted]ngHKNhh
</BinarySecurityToken>
<EncryptedKey xmlns="http://www.w3.org/2001/04/xmlenc#">
<EncryptionMethod Algorithm="[parts omitted]xmlenc#rsa-oaep-mgf1p">
<DigestMethod xmlns="http://www.w3.org/2000/09/xmldsig#"
Algorithm="http://www.w3.org/2000/09/xmldsig#sha1">
</DigestMethod>
</EncryptionMethod>
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<SecurityTokenReference
xmlns="[parts omitted]oasis-200401-wss-wssecurity-secext-1.0.xsd">
<Reference URI="#SecurityToken-4EC1997A-AD6B-48E3-9E91-8D50C8EA3B53"
ValueType="[parts omitted]#X509v3"></Reference>
</SecurityTokenReference>
</KeyInfo>
<CipherData>
<CipherValue>WtE[parts omitted]bSyvg==</CipherValue>
</CipherData>
<ReferenceList>
<DataReference URI="#Enc-143BBBAA-B75D-49EB-86AC-B414D818109F"></DataReference>
</ReferenceList>
</EncryptedKey>
</Security>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<EncryptedData xmlns="http://www.w3.org/2001/04/xmlenc#"
Id="Enc-143BBBAA-B75D-49EB-86AC-B414D818109F"
Type="http://www.w3.org/2001/04/xmlenc#Content">
<EncryptionMethod Algorithm="[parts omitted]#aes128-cbc"></EncryptionMethod>
<CipherData>
<CipherValue>MLwR6hvKE0gon[parts omitted]8njiQ==</CipherValue>
</CipherData>
</EncryptedData>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>