デジタル・シグニチャの追加
このトピックでは、InterSystems IRIS Web サービスおよび Web クライアントによって送信される SOAP メッセージにデジタル・シグニチャを追加する方法について説明します。
通常、暗号化と署名の両方を実行します。このトピックでは、説明を簡単にするために、署名のみについて説明します。暗号化と署名の組み合わせに関する詳細は、"暗号化と署名の組み合わせ" のトピックを参照してください。
"暗号化および署名への派生キー・トークンの使用" のトピックでは、さらに別の方法で SOAP メッセージにデジタル・シグニチャを追加する方法について説明します。
デジタル・シグニチャの概要
デジタル・シグニチャを使用して、メッセージの変更を検出したり、リストされているエンティティによってメッセージの特定の部分が実際に生成されたことを検証したりできます。従来の手書きの署名と同様に、デジタル・シグニチャは、ドキュメントの作成者のみが作成できるドキュメントへの追加物で、簡単に偽造することはできません。
SOAP メッセージのデジタル・シグニチャに対する InterSystems IRIS サポートは、WS-Security 1.1 を基盤としています。また、WS-Security は、XML シグニチャ仕様に従います。後者の仕様に従って、XML ドキュメントに署名する方法は、以下のとおりです。
-
ダイジェスト関数を使用して、ドキュメントの複数の部分のハッシュ値を計算します。
-
ダイジェスト値を連結します。
-
秘密鍵を使用して、連結されたダイジェストを暗号化します(これは、ユーザのみが実行できる計算です)。
-
以下の情報を含む <Signature> 要素を作成します。
-
署名済み部分への参照 (このシグニチャを適用するメッセージの部分を示します)。
-
暗号化されたダイジェスト値。
-
暗号化されたダイジェスト値の解読に使用する公開鍵を受信者が特定できる情報。
この情報は、<Signature> 要素内に含めることができます。または、<Signature> 要素は、X.509 証明書または署名済みの SAML アサーションを格納しているバイナリ・セキュリティ・トークンへの直接参照を含めることができます。後者の場合、<Signature> 要素を追加する前にセキュリティ・トークンをメッセージに追加する必要があります。
この情報を使用すると、ユーザが公開鍵と秘密鍵のペアの所有者であることを受信者が検証することもできます。
-
"暗号化および署名への派生キー・トークンの使用" のトピックでは、さらに別の方法で SOAP メッセージにデジタル・シグニチャを追加する方法について説明します。メッセージ自体の詳細はさまざまですが、一般的なプロセスは同じで、XML 署名仕様に従います。つまり、署名済みの部分のダイジェストを生成し、そのダイジェストを暗号化してから、受信者がシグニチャを検証して暗号化されたダイジェストを解読できる情報を含む <Signature> 要素を組み込みます。
デジタル・シグニチャの追加
SOAP メッセージをデジタル署名するには、次に説明する基本的な手順を使用するか、またはこのトピックの次の部分で説明するバリエーションを使用します。
まず、次の図にプロセスを示します。
詳細なプロセスは以下のとおりです。
-
必要に応じて、%soap.inc インクルード・ファイルを組み込みます。このファイルには、使用する可能性のあるマクロが定義されています。
-
任意のセキュリティ・ヘッダ要素に署名する場合、そのセキュリティ・ヘッダ要素を作成します。以下はその例です。
set utoken=##class(%SOAP.Security.UsernameToken).Create("_SYSTEM","SYS")
-
"プログラムによる資格情報セットの取得" の説明に従って、%SYS.X509CredentialsOpens in a new tab のインスタンスを作成します。この InterSystems IRIS 資格情報セットには、独自の証明書を格納する必要があります。また、秘密鍵のパスワードを入力する必要があります (まだロードされていない場合)。以下はその例です。
Set x509alias = "servercred" Set pwd = "mypassword" Set credset = ##class(%SYS.X509Credentials).GetByAlias(x509alias,mypassword)
-
その資格情報セットに関連付けられている証明書を含むバイナリ・セキュリティ・トークンを作成します。これには、%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)
-
バイナリ・セキュリティ・トークンに基づいて、<Signature> 要素を作成します。これには、%XML.Security.SignatureOpens in a new tab の CreateX509() クラス・メソッドを呼び出します。以下はその例です。
set dsig=##class(%XML.Security.Signature).CreateX509(bst)
このメソッドは、<Signature> ヘッダ要素を表す %XML.Security.SignatureOpens in a new tab のインスタンスを返します。<Signature> 要素は、メッセージの既定の部分に適用されます。また、異なる部分を指定できます。
最後に、このメソッドには、以下のシグニチャがあります。
classmethod CreateX509(credentials As %SYS.X509Credentials = "", signatureOptions As %Integer, referenceOption As %Integer, Output status As %Status) as %XML.Security.Signature
以下はその説明です。
-
credentials は、%SYS.X509CredentialsOpens in a new tab インスタンス、%SAML.AssertionOpens in a new tab インスタンス、または %SOAP.Security.BinarySecurityTokenOpens in a new tab インスタンスのいずれかです。
-
signatureOptions は、署名する部分を指定します。このオプションは、"メッセージの特定部分へのデジタル・シグニチャの適用" で説明します。
-
referenceOption は、作成する参照のタイプを指定します。詳細は、"X.509 資格情報の参照オプション" を参照してください。
-
status は、メソッドが成功したかどうかを示します。
-
-
WS-Security ヘッダ要素にデジタル・シグニチャを追加します。そのためには、Web クライアントまたは Web サービスの SecurityOut プロパティの AddSecurityElement() メソッドを呼び出します。引数に、前の手順で作成したシグニチャ・オブジェクトを指定します。以下はその例です。
do ..SecurityOut.AddSecurityElement(dsig)
-
SOAP メッセージを送信します。"セキュリティ・ヘッダ要素の追加" の一般的な手順を参照してください。
例
この例では、その応答メッセージに署名する Web サービスを示します。
個々の環境でこの例のとおり機能するようにするには、まず次の手順を実行します。
-
サーバ用の証明書を作成します。
-
サーバ側で InterSystems IRIS にこの証明書をロードし、servercred という名前で資格情報を作成します。このとき、(Web サービスがその応答メッセージに署名する際、パスワードを指定しないで済むように) 秘密鍵ファイルもロードし、パスワードを指定します。
Web サービスは、この正確な名前で InterSystems IRIS 資格情報セットを参照します。
Class DSig.DivideWS Extends %SOAP.WebService
{
/// Name of the Web service.
Parameter SERVICENAME = "DigitalSignatureDemo";
/// SOAP namespace for the Web service
Parameter NAMESPACE = "http://www.myapp.org";
/// use in documentation
Method Divide(arg1 As %Numeric = 2, arg2 As %Numeric = 8) As %Numeric [ WebMethod ]
{
Do ..SignResponses()
Try {
Set ans=arg1 / arg2
}Catch{
Do ..ApplicationError("division error")
}
Quit ans
}
/// use in documentation
/// signs and includes a binary security token
Method SignResponses()
{
//Add timestamp because that's commonly done
Set ts=##class(%SOAP.Security.Timestamp).Create()
Do ..SecurityOut.AddSecurityElement(ts)
//access previously stored server certificate & private key file
//no need to use private key file password, because that has been saved
Set x509alias = "servercred"
Set cred = ##class(%SYS.X509Credentials).GetByAlias(x509alias)
set bst=##class(%SOAP.Security.BinarySecurityToken).CreateX509Token(cred)
do ..SecurityOut.AddSecurityElement(bst)
//Create WS-Security Signature object
Set signature=##class(%XML.Security.Signature).CreateX509(bst)
//Add WS-Security Signature object to the outbound message
Do ..SecurityOut.AddSecurityElement(signature)
Quit
}
/// Create our own method to produce application specific SOAP faults.
Method ApplicationError(detail As %String)
{
Set fault=##class(%SOAP.Fault).%New()
Set fault.faultcode=$$$FAULTServer
Set fault.detail=detail
Set fault.faultstring="Application error"
// ReturnFault must be called to send the fault to the client.
// ReturnFault will not return here.
Do ..ReturnFault(fault)
}
}
証明書とシグニチャを使用するその他の方法
前のセクションで説明した基本的な手順では、シリアル化された Base 64 エンコード形式を含む <BinarySecurityToken> を使用します。証明書を組み込む代わりに、証明書を識別する情報を使用できます。または、署名済みの SAML アサーション内に証明書を入れることもできます。このセクションでは、これらのバリエーションについて説明します。
バリエーション :証明書を指定する情報の使用
証明書をメッセージに組み込む代わりに、証明書を識別する情報を使用できます。受信者はこの情報を使用して、適切な場所から証明書を取得します。そのためには、前のセクションの手順を使用しますが、以下の変更点があります。
-
手順 4 と 5 をスキップします。つまり、<BinarySecurityToken> を追加しないでください。
-
手順 6 (シグニチャの作成) で、CreateX509() の最初の引数として手順 1 の資格情報セットを使用します (バイナリ・セキュリティ・トークンは使用しません)。以下はその例です。
set dsig=##class(%XML.Security.Signature).CreateX509(credset,,referenceOption)
3 番目の引数 (referenceOption) では、<Signature> 要素が証明書を使用する方法を指定できます。
(このバリエーションで実行しているように) 最初の引数として資格情報セットを指定する場合、referenceOption の既定値は $$$SOAPWSReferenceThumbprint です。必要に応じて、"X.509 資格情報の参照オプション" の説明に従って、値を指定します。$$$SOAPWSReferenceDirect 以外の任意の値を使用できます。
例
この例は、このトピックの前の例のバリエーションです。
Method SignResponses()
{
//Add timestamp because that's commonly done
Set ts=##class(%SOAP.Security.Timestamp).Create()
Do ..SecurityOut.AddSecurityElement(ts)
//access previously stored server certificate & private key file
//no need to use private key file password, because that has been saved
Set x509alias = "servercred"
Set cred = ##class(%SYS.X509Credentials).GetByAlias(x509alias)
//Create WS-Security Signature object
Set signature=##class(%XML.Security.Signature).CreateX509(cred)
//Add WS-Security Signature object to the outbound message
Do ..SecurityOut.AddSecurityElement(signature)
Quit
}
この場合、この Web サービスは、次のような応答メッセージを送信します。
<?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">
<Timestamp xmlns="[parts omitted]oasis-200401-wss-wssecurity-utility-1.0.xsd"
wsu:Id="Timestamp-48CEE53E-E6C3-456C-9214-B7D533B2663F">
<Created>2010-03-19T14:35:06Z</Created>
<Expires>2010-03-19T14:40:06Z</Expires>
</Timestamp>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
</CanonicalizationMethod>
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha256"></SignatureMethod>
<Reference URI="#Timestamp-48CEE53E-E6C3-456C-9214-B7D533B2663F">
<Transforms>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></Transform>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></DigestMethod>
<DigestValue>waSMFeYMruQn9XHx85HqunhMGIA=</DigestValue>
</Reference>
<Reference URI="#Body-73F08A5C-0FFD-4FE9-AC15-254423DBA6A2">
<Transforms>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></Transform>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></DigestMethod>
<DigestValue>wDCqAzy5bLKKF+Rt0+YV/gxTQws=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>j6vtht/[parts omitted]trCQ==</SignatureValue>
<KeyInfo>
<SecurityTokenReference
xmlns="[parts omitted]oasis-200401-wss-wssecurity-secext-1.0.xsd">
<KeyIdentifier EncodingType="[parts omitted]#Base64Binary"
ValueType="[parts omitted]#ThumbprintSHA1">
WeCnU2sMyOXfHH8CHTLjNTQQnGQ=
</KeyIdentifier>
</SecurityTokenReference>
</KeyInfo>
</Signature>
</Security>
</SOAP-ENV:Header>
<SOAP-ENV:Body wsu:Id="Body-73F08A5C-0FFD-4FE9-AC15-254423DBA6A2">
[omitted]
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
バリエーション :署名済みの SAML アサーションの使用
署名済みの SAML アサーションの証明書を使用するデジタル・シグニチャを追加するには、以下の手順を実行します。
-
必要に応じて、%soap.inc インクルード・ファイルを組み込みます。このファイルには、使用する可能性のあるマクロが定義されています。
-
任意のセキュリティ・ヘッダ要素に署名する場合、そのセキュリティ・ヘッダ要素を作成します。以下はその例です。
set utoken=##class(%SOAP.Security.UsernameToken).Create("_SYSTEM","SYS")
-
Holder-of-key メソッドを使用する <SubjectConfirmation> 要素を使用して、署名済みの SAML アサーションを作成します。"SAML トークンの作成と追加" を参照してください。
-
<Signature> 要素を作成します。そのためには、CreateX509() クラス・メソッドの最初の引数として署名済みの SAML アサーションを使用します。以下はその例です。
set signature=##class(%XML.Security.EncryptedKey).CreateX509(signedassertion)
-
WS-Security ヘッダ要素にデジタル・シグニチャを追加します。そのためには、Web クライアントまたは Web サービスの SecurityOut プロパティの AddSecurityElement() メソッドを呼び出します。引数に、前の手順で作成したシグニチャ・オブジェクトを指定します。以下はその例です。
do ..SecurityOut.AddSecurityElement(dsig)
-
SOAP メッセージを送信します。"セキュリティ・ヘッダ要素の追加" の一般的な手順を参照してください。
メッセージの特定部分へのデジタル・シグニチャの適用
既定では、デジタル・シグニチャを作成し、WS-Security ヘッダ要素に追加する場合、シグニチャは、SOAP 本文、ヘッダの <Timestamp> 要素 (ある場合)、およびすべての WS-Addressing ヘッダ要素に適用されます。
シグニチャを適用する部分を指定するには、1 つのバリエーションで前に説明した手順のいずれかを使用します。つまり、シグニチャを作成するとき、2 番目の引数 (signatureOptions) を使用して、署名するメッセージ部分を指定します。この引数は、以下のマクロ (%soap.inc ファイルに保存) のいずれかのバイナリの組み合わせとして指定します。
-
$$$SOAPWSIncludeNone
-
$$$SOAPWSIncludeDefault ($$$SOAPWSIncludeSoapBody + $$$SOAPWSIncludeTimestamp + $$$SOAPWSIncludeAddressing に相当)
-
$$$SOAPWSIncludeSoapBody
-
$$$SOAPWSIncludeTimestamp
-
$$$SOAPWSIncludeAddressing
-
$$$SOAPWSIncludeAction
-
$$$SOAPWSIncludeFaultTo
-
$$$SOAPWSIncludeFrom
-
$$$SOAPWSIncludeMessageId
-
$$$SOAPWSIncludeRelatesTo
-
$$$SOAPWSIncludeReplyTo
-
$$$SOAPWSIncludeTo
-
$$$SOAPWSIncludeRMHeaders ("WS-ReliableMessaging の使用" を参照)
マクロを組み合わせるときには、プラス記号 (+) とマイナス記号 (-) を使用します。以下はその例です。
$$$SOAPWSIncludeSoapBody+$$$SOAPWSIncludeTimestamp
これらのオプションは、CreateX509() メソッドと Create() メソッドの両方に適用されます。後者については、"暗号化および署名への派生キー・トークンの使用" を参照してください。
以下はその例です。
set ts=##class(%SOAP.Security.Timestamp).Create()
do ..SecurityOut.AddSecurityElement(ts)
set x509alias = "servercred"
set cred = ##class(%SYS.X509Credentials).GetByAlias(x509alias)
set parts=$$$SOAPWSIncludeSoapBody + $$$SOAPWSIncludeTimestamp
set signature=##class(%XML.Security.Signature).CreateX509(cred,parts)
ダイジェスト・メソッドの指定
既定では、シグニチャのダイジェスト値は、SHA-1 アルゴリズムを使用して計算され、セキュリティ・ヘッダの <Signature> 要素は以下の例のようになります。
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></DigestMethod>
<DigestValue>waSMFeYMruQn9XHx85HqunhMGIA=</DigestValue>
シグニチャには異なるダイジェスト・メソッドを指定することもできます。そのためには、%XML.Security.SignatureOpens in a new tab のインスタンスの SetDigestMethod() メソッドを呼び出します。引数には、以下のマクロ (%soap.inc ファイルに保存) のいずれかを使用します。
-
$$$SOAPWSsha1 (既定)
-
$$$SOAPWSsha256
-
$$$SOAPWSsha384
-
$$$SOAPWSsha512
以下はその例です。
do sig.SetDigestMethod($$$SOAPWSsha256)
シグニチャ・メソッドの指定
既定では、シグニチャ値は、RSA-SHA256 アルゴリズムを使用して計算され、セキュリティ・ヘッダの <Signature> 要素は以下の例のようになります。
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha256"></SignatureMethod>
...
<SignatureValue>J+gACmdjkJxaq2hJqA[parts omitted]</SignatureValue>
シグニチャ・メソッドには異なるアルゴリズムを指定することもできます。そのためには、%XML.Security.SignatureOpens in a new tab のインスタンスの SetSignatureMethod() メソッドを呼び出します。引数には、以下のマクロ (%soap.inc ファイルに保存) のいずれかを使用します。
-
$$$SOAPWSrsasha1
-
$$$SOAPWSrsasha256 (既定)
-
$$$SOAPWSrsasha384
-
$$$SOAPWSrsasha512
-
$$$SOAPWShmacsha256
-
$$$SOAPWShmacsha384
-
$$$SOAPWShmacsha512
以下はその例です。
do sig.SetSignatureMethod($$$SOAPWSrsasha512)
既定のシグニチャ・アルゴリズムは変更できないことに注意してください。変更するには、管理ポータルにアクセスし、[システム管理]、[セキュリティ]、[システムセキュリティ]、[システムワイドセキュリティパラメータ] の順にクリックします。既定のシグニチャ・アルゴリズムを指定するオプションには、[既定のシグニチャ・ハッシュ] というラベルが付いています。
<KeyInfo> の正規化メソッドの指定
既定では、<KeyInfo> 要素が Exclusive XML Canonicalization によって正規化され、<KeyInfo> 要素は以下を含みます。
<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
その代わりに、Inclusive XML Canonicalization によってこの要素を正規化する場合は、以下の手順を実行します。
Set sig.SignedInfo.CanonicalizationMethod.Algorithm=$$$SOAPWSc14n
sig は、%XML.Security.SignatureOpens in a new tab のインスタンスです。
この場合、<KeyInfo> は以下の要素で構成されます。
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315">
シグニチャの確認の追加
WS-Security 1.1 <SignatureConfirmation> 機能は、受信した SOAP メッセージが、Web クライアントによって送信された元の要求への応答で生成されたことを、Web クライアントが確認できるようにします。クライアント要求は通常、署名されますが、署名は必須ではありません。このメカニズムでは、Web サービスは、セキュリティ・ヘッダ要素に <SignatureConfirmation> 要素を追加し、Web クライアントは、その <SignatureConfirmation> 要素を検証できます。
Web サービスの場合、セキュリティ・ヘッダ要素に <SignatureConfirmation> 要素を追加するには、次の操作を実行します。
-
Web サービスの WSAddSignatureConfirmation() メソッドを呼び出します。引数に、セキュリティ・ヘッダ要素の主要なシグニチャを指定します。以下はその例です。
do ..WSAddSignatureConfirmation(sig)
-
通常どおり、SOAP メッセージを送信します。"セキュリティ・ヘッダ要素の追加" の一般的な手順を参照してください。
このメソッドでは、発信メッセージに WS-Security 1.1 <SignatureConfirmation> 要素が追加されます。SecurityIn で受信された各 <Signature> の SecurityOut プロパティに <SignatureConfirmation> 要素が追加されます。
SecurityIn にシグニチャが含まれていない場合、<SignatureConfirmation> 要素は、WS-Security 1.1 によって要求されているとおり Value 属性なしで追加されます。
<SignatureConfirmation> 要素を検証する方法については、"シグニチャの確認のチェック" を参照してください。