9 Oracle Web Services Security
Oracle Web Services Securityでは、OASIS WS Security 1.1規格の完全な実装が提供されます。メッセージの署名および暗号化のメカニズムと、送信者のアイデンティティを確定するためのセキュリティ・トークンが提供されます。
この章では、SDKのインストールおよび使用方法について説明します。この章には次のトピックが含まれます:
9.1 Oracle Web Services Securityの環境設定
Oracle Web Services Securityの環境を設定するには、Oracle Security Developer ToolsとJava Development Kit (JDK)をインストールし、必要なすべてのjarファイルへのCLASSPATH変数を設定します。
Oracle Security Developer Toolsは、Oracle Application ServerとともにORACLE_HOMEにインストールされます。
Oracle Web Services Securityを使用するには、Development Kit (JDK)バージョン1.6以上が必要です。
次の項目をCLASSPATHに指定します。
-
osdt_core.jar -
osdt_cert.jar -
osdt_xmlsec.jar- Oracle XML Security jarです。 -
osdt_saml.jar- Oracle SAML 1.0および1.1 jarです。 -
osdt_saml2.jar- Oracle SAML 2.0 jarです。 -
org.jaxen_1.1.1.jar:$ORACLE_HOME/modules/に含まれます。 -
osdt_wss.jar- Oracle Web Services Securityを含むメインjarです。 -
saaj-api.jar- 標準のSAAJ APIでJDK6に含まれます。以前のJDKの場合、JavaEEコンテナから取得できます。 -
mail.jar、activation.jar- これらのjarはJavaEEコンテナから取得できます。
関連項目:
9.2 Oracle Web Services Securityのクラスおよびインタフェース
Oracle Web Services Securityは、メッセージを署名して暗号化するためのクラス、インタフェースおよびメソッドと、送信者のアイデンティティを確定するためのセキュリティ・トークンを提供します。
注意:
続行する前に、Oracle XML Securityを確認してください。
この項では、Oracle Web Services SecurityのAPIのクラスおよびインタフェースについて説明します。この項の内容は、次のとおりです。
9.2.1 Oracle Web Services Securityの要素ラッパー
Oracle Web Services Securityでは、すべてのXML要素に対して要素ラッパーが提供されます。
表9-1に、Oracle Web Services Securityで提供される要素ラッパーを示します。
表9-1 Oracle Web Services Securityの要素ラッパー
| XMLタグ名 | Javaクラス名 |
|---|---|
|
<wsse:Security> |
oracle.security.xmlsec.wss.WSSecurity |
|
<wsse:BinarySecurityToken> |
oracle.security.xmlsec.wss.WSSBinarySecurityTokenまたは導出されたクラス(valueType属性に応じてoracle.security.xmlsec.wss.x509.X509BinarySecurityTokenまたはoracle.security.xmlsec.wss.kerberos.KerberosBinarySecurityToken) |
|
<wsse: SecurityTokenReference> |
oracle.security.xmlsec.wss.WSSecurityTokenReference |
|
<wsse: Embedded> |
oracle.security.xmlsec.wss.WSSEmbedded |
|
<wsse11:EncryptedHeader> |
oracle.security.xmlsec.wss.WSSEncryptedHeader |
|
<wsse11:SignatureConfirmation> |
oracle.security.xmlsec.wss.WSSignatureConfirmation |
|
<wsse:KeyIdentifier> |
oracle.security.xmlsec.wss.WSSKeyIdentifierまたは導出されたクラス(valueType属性に応じて、oracle.security.xmlsec.wss.x509.X509KeyIdentifier、oracle.security.xmlsec.wss.saml.SAMLAssertionKeyIdentifier、oracle.security.xmlsec.wss.saml2.SAML2AssertionKeyIdentifier、oracle.security.xmlsec.wss.kerberos.KerberosKeyIdentifierまたはoracle.security.xmlsec.wss.WSSEncryptedKeyIdentifier) |
|
<wsse:Reference> |
oracle.security.xmlsec.wss.WSSReference |
|
<wsu:Created> |
oracle.security.xmlsec.wss.WSUCreated |
|
<wsu:Expires> |
oracle.security.xmlsec.wss.WSUExpires |
|
<wsu:Timestamp> |
oracle.security.xmlsec.wss.WSUTimestamp |
|
<wsse:UsernameToken> |
oracle.security.xmlsec.wss.username.UsernameToken、oracle.security.xmlsec.wss、oracle.security.xmlsec.wss、oracle.security.xmlsec.wss、oracle.security.xmlsec.wss、oracle.security.xmlsec.wss、oracle.security.xmlsec.wss |
「OSDT XML APIでの要素ラッパーの理解および使用方法」で説明しているように、Javaクラスは棄却型ラッパーにすぎませんが、DOM要素は真のソースです。これらのラッパー・クラスは、DOM要素を取り込む適切なコンストラクタを使用して作成できます。基礎となるDOM要素はgetElementメソッドを使用して取得できます。
9.2.2 <wsse:Security>ヘッダー
WS Security仕様では、<wsse:Security>と呼ばれる新しいSOAPヘッダーが定義されています。セキュリティ・トークン、タイムスタンプ、署名、EncryptedKey、ReferenceListなど、すべてのセキュリティ情報がこのヘッダー内に格納されます。
-
セキュリティ・トークン - ユーザー名トークン、証明書、SAMLアサーションなどを格納します(次の項を参照)。
-
タイムスタンプ - 現在のタイムスタンプは、多くの場合セキュリティ・ヘッダーに含まれ、リプレイ攻撃を防ぐために、通常は署名に含まれます。
-
署名 - すべての署名はヘッダー内に格納されます。署名が
Securityヘッダーにある場合でも、署名対象は多くの場合ヘッダーの外部になり、たとえば、1つの署名でSOAP本文、複数のSOAP添付ファイル、Securityヘッダー内のUserNameトークン、およびSecurityヘッダー内のTimestampトークンに署名できます。 -
EncryptedKey - 暗号化されたすべてのセッション・キーはここに格納されます。
-
ReferenceList - すべての
EncryptedDataセクションのリストを格納します。
9.2.2.1 送信メッセージの処理
送信メッセージの場合は、新しい<wsse:Security>ヘッダーを作成して、セキュリティ・トークンを追加し、文書の一部を暗号化または署名(あるいはその両方を実行)する必要があります。このタスクを実行する方法は、次のとおりです。
// Assuming we the outgoing message has already been constructed into // a SOAPMessage object (part of SAAJ API) SOAPMessage msg = ... // Now create a new <wsse:Security> Header // newInstance will internally use SOAPHeader.addHeaderElement SOAPEnvelope env = msg.getSOAPPart().getEnvelope(); WSSecurity ws = WSSecurity.newInstance(env); // Add required prefixes to this SOAP header // Now add some security tokens (refer to the next section on // how to create security tokens) UsernameToken ut = ... ws.addUsernameToken(ut); // Create some security token references to this token // (refer to following sections) ws.createSTR... // Now sign or encrypt some data (refer to following sections) // These should use the above STRs ws.sign(...); ws.encryptWithEncKey(...); ws.encryptNoEncKey(...);
9.2.3 Oracle Web Services Securityのセキュリティ・トークン(ST)
セキュリティ・トークンは、証明書、Kerberosチケット、パスワード付きのユーザー名、シングル・サインオンのトークンなどのアーティファクトを表します。Oracle Web Services Securityには、ユーザー名トークン、X509証明書、Kerberosチケット、SAMLアサーションなど、様々なタイプのセキュリティ・トークンが含まれています。また、これらのセキュリティ・トークンには複数のバリエーションがあります。
通常、キーはこのトークンから導出および抽出され、メッセージの一部の暗号化、復号化、署名および検証に使用されます。これに対し、セキュリティ・トークンはデータ・オブジェクトと同じように使用することもできます。
表9-2 Oracle Web Services Securityのセキュリティ・トークン
| トークンのタイプ(Javaクラス) | バリエーション | キー |
|---|---|---|
|
ユーザー名トークン oracle.security.xmlsec.wss.username。UsernameToken |
|
ユーザーのパスワードでKeyDerivationを実行して取得した対称キー |
|
X509証明書 oracle.security.xmlsec.wss.x509。X509BinarySecurityToken |
|
|
|
Kerberosチケット oracle.security.xmlsec.wss.kerberos。KerberosBinarySecurityToken |
|
チケットに存在するセッション・キー、またはサブキー。 |
|
SAMLアサーション1.1 oracle.security.xmlsec.wss.saml.SAMLAssertionToken SAMLアサーション2.0 oracle.security.xmlsec.wss.saml2。SAML2AssertionToken |
|
holder_of_keyの場合は、サブジェクトのキー(<saml:Assertion>内にある<saml:SubjectConfirmation>内のキー)が使用されます。 sender_vouchesの場合は、証明元のエンティティのキーが使用されます。 キーはbearerトークンからは抽出されません。 |
9.2.3.1 WSSユーザー名トークンの作成
最初に、UsernameTokenを作成し、WSSecurityヘッダー内に配置します。UsernameToken内の唯一の必須フィールドは、次のようにユーザー名です。
// create a Username token
WSSecurity ws = ...
UsernameToken ut = new UsernameToken(doc);
ut.setUserName("Zoe");
// remember to put this inside your WSSecurity header.
// addUserNameToken puts it at the beginning, you can also
// use a regular DOM method appendChild or insertChild to put it in.
ws.addUsernameToken(ut);
// optionally add an wsu:Id, so you can refer to it
ut.setWsuId("MyUser");
次に、このトークンにパスワードを配置する方法を決定します。次のように複数の方法を選択できます。
- クリア・テキスト・パスワードを追加します。この方法は、メッセージ全体がSSLなどのセキュアなチャネルで送信されている場合にのみ考慮します。
- パスワードのダイジェストまたはその他の種類の導出されたパスワードのダイジェストを追加します。ダイジェストは、nonceと時間によって保護されないかぎりリプレイすることもできるため、クリア・テキスト・パスワードよりも必ずしも安全とはかぎりません。
- WS Security仕様で指定されているダイジェスト・メカニズムを使用してパスワードのダイジェストを追加します。この方法では、nonceと
createdDateを使用します。 - パスワードまたはそのダイジェストをまったく追加しません。キーを知っていることを示すには、かわりにパスワードからキーを導出し、そのキーをメッセージの署名に使用します。
// For options 1 and 2, use the setPassword method
ut.setPassword("IloveDogs");
// With this mechanism, the reciever should simply call
// UsernameToken.getPassword to check if the password is as expected.
// For option 3, use the setPasswordDigest method, but before doing
// thatfor that you have to at first set a nonce and a created date.
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
byte nonce[] = new byte[20];
random.nextBytes(nonce); // compute a 20 byte random nonce
ut.setNonce(nonce);
ut.setCreatedDate(new Date()); // Set the date to now
ut.setPasswordDigest("IloveDogs"); // will compute the digest from
// this clear text password using
// nonce and createdDate
// For this mechanism, the reciever should use the following
byte nonce[] = ut.getNonce();
.. check against the used nonces, to make sure this is a new nonce
Date createdDate = ut.getCreated();
.. check that this createdDate is within an expected clock skew
boolean valid = ut.isValid(userName, passwd),
// above call will recompute the digest from the passwd
// and the nonce and created date, and check if this digest matches
// the digest in the username token
// For option 4, set the salt and iteration count
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
byte salt[] = new byte[15];
random.nextBytes(salt); // compute a 15 byte random salt
ut.setSalt(1, salt);
ut.setIteration(1000);
SecretKey key = ut.deriveKey("IloveDogs");
これで、この秘密キーを使用してデータを署名または暗号化できます。
9.2.3.2 X509トークンの作成
次のように、X509BinarySecurityTokenコンストラクタの後にsetTokenメソッドを使用するか、または同等のヘルパー・メソッドWSSecurity.createBST_X509を使用できます。
WSSecurity ws = ...
X509Certificate cert = ...
X509BinarySecurityToken x509token = WSSecurity.createBST_X509(cert);
// remember to put this inside your WSSecurity header.
// addX509CertificateToken puts it at the beginning, you can also
// use a regular DOM method appendChild or insertChild to put it in.
ws.addX509CertificateToken(x509Token);
// optionally add an wsu:Id, so you can refer to it
x509Token.setWsuId("MyCert");
証明連鎖全体を含める場合は、CertPathオブジェクトからX509BinarySecurityTokenを作成することもできます。
この証明書でデータを暗号化する場合は、cert.getPublicKey()を使用して取得できる公開キーが必要です。これに対し署名の場合は、キーストアに保持する必要がある秘密キーが必要です。
9.2.3.3 クライアント側Kerberosトークンの作成
一般的に、KerberosトークンはJava GSS-APIと組み合せて使用します。
次の例に、クライアント側トークンの作成方法を示します。
//Use JAAS Authentication with Kerberos Login Module
// Set up the config files and then call login()
// to login using this module. This will cause the client to contact
// the Kerberos Authentication-Service and get a ticket to talk to the
// Kerberos Ticket-Granting-Service
LoginContext lc = new LoginContext(...);
lc.login();
//Use JAAS Authorization to set the subject into the thread context
Subject.doAs(lc.getSubject(), action)
// The rest of the code should be executed as a Privileged action
// Create a GSSContext to talk to a particular server.
GSSManager gssManager = GSSManager.getInstance();
GSSName serviceName = gssManager.createName(svcPrincipalName, null);
GSSContext gssContext = gssManager.createContext(serviceName, null,
null, GSSCredential.DEFAULT_LIFETIME);
// Then call initSecContext. this will cause the client to contact
// the Ticket-Granting-Service to obtain a ticket for talking to that
// particular server. The token that is returned by the initSecContext
// is a GSS wrapped AP_REQ packet.
byte[] token = new byte[1];
token = gssContext.initSecContext(token, 0, token.length);
// Create a Kerberos BST using this AP_REQ packet
WSSecurity ws = ...
KerberosBinarySecurityToken kbst = ws.createBST_Kerberos(token,
WSSURI.vt_GSSKerberosv5);
ws.addKerberosToken(kbst);
// Get the sessionKey that is present inside the AP_REQ packet,
// this is the session that is generated by the TGT and returned
// to the client in the initSecContext class
//
// This getSessionKey call simply calls Subject.getPrivateCredentials
// to get a list of tickets associated with the subject, and then
// iterates through them to find the one to be used for
// for that particular server
SecretKey sessionKey =
KerberosUtils.getSessionKey(lc.getSubject(),svcPrincipalName);
これで、この秘密キーを使用してデータを署名または暗号化できます。
サーバー側
9.2.3.4 サーバー側Kerberosトークンの作成
サーバー側kerberosトークンには、GSSContextの作成とセッション・キーの抽出が必要です。
次の例に、サーバー側kerberosトークンの作成方法を示します。
// Use JAAS Authentication and Authorization as for the client // Create GSSContext will null credentials </b><br> SSManager manager = GSSManager.getInstance(); GSSContext gssContext = manager.createContext((GSSCredential)null); // Locate the KerberosBinarySecurityToken in the incoming WSSecurity // header. You can do this by doing a DOM search WSSecurity = ... KerberosBinarySecurityToken kbst = ... // Now extract the AP_REQ from the BST and call acceptSecContext byte ap_req[] = kbst.getValue(); gssContext.acceptSecContext(ap_req); // The context is now extablished. (Note Mutual authentication would // need one more round trip) // Now extract the session key // KerberosUtils.getSession is an overloaded method, and this // particular one is meant to be used by server. Internally // it decrypts the ap_req packet using the server's key (or the // tgtSession key) and extracts the key from the decrypted ap_req // packet Subject srvrSubject = ... SecretKey sessionKey = KerberosUtils.getSessionKey(srvrSubject, ap_req);
これで、このキーを使用して復号化または検証できます。
9.2.3.5 SAMLアサーション・トークンの作成
Assertionオブジェクトの作成方法の詳細は、Oracle XML Securityを参照してください。SAMLアサーション・トークンは、SAMLAssertionToken(Assertion assertion)コンストラクタを起動するだけでAssertionオブジェクトから作成できます。
9.2.4 セキュリティ・トークン参照(STR)
WS Security仕様には、セキュリティ・トークンを参照するメカニズムであるセキュリティ・トークン参照(STR)の概念も定義されています。SignatureまたはEncryptionでは、このSTRメカニズムを使用して、署名または暗号化に使用したキーを識別します。STRでは、直接参照、キー識別子、埋込みなどのメカニズムがサポートされています。
通常、STRでは次のメカニズムをサポートしています。
-
直接参照: STRではURIを使用してSTを参照します。
-
キー識別子: STRでは、トークンの識別にURIではなく、
発行者のシリアル(X509トークンの場合)やアサーションID (SAMLトークンの場合)などの別のメカニズムを使用します。トークンがメッセージに存在しない場合もあります。 -
埋込み: トークンは
KeyInfoに直接埋め込まれます。
9.2.4.1 直接参照STRの作成
STRは同一の手順を使用して作成されます。STRを渡すメカニズムはトークンのタイプにより異なります。
STRを作成する手順:
- 前述のとおりトークンを作成します。
.setWsuId()をコールしてそのトークンにIDを設定します- ステップ2のIDを使用してSTRを作成します
WSSSignatureParamsまたはWSEncryptionParams内でそのSTRを渡します
後続の項では様々なトークンに対するSTRを渡す方法について示します。
9.2.4.2 ユーザー名トークンの参照STRの作成
次の例に、ユーザー名トークンの参照STRの作成方法を示します。
WSSecurity ws = ...
WSSecurityTokenReference str =
ws.createSTR_Username_ref("#MyUser");
9.2.4.3 X509トークンの参照STRの作成
次の例に、X509トークンの参照STRの作成方法を示します。
WSSecurity ws = ...
WSSecurityTokenReference str =
ws.createSTR_X509_Ref("#MyCert");
9.2.4.4 Kerberosトークンの参照STRの作成
次の例に、kerberosトークンの参照STRの作成方法を示します。
WSSecurity ws = ... // use the appropriate value type String valueType = WSSURI.vt_GSSKerberosv5; WSSecurityTokenReference str = ws.createSTR_KerberosKeyRef ( "#MyToken");
9.2.4.5 SAMLアサーション・トークンの参照STRの作成
この例では、SAMLアサーション・トークンの参照STRの作成方法を示します。
WSSecurity ws = ...
WSSecurityTokenReference str =
ws.createSTR_SAML_Assertion_Ref20("MySAMLAssertion")
9.2.4.6 EncryptedKeyの参照STRの作成
次の例に、暗号化キーの参照STRの作成方法を示します。
WSSecurity ws = ...
WSSecurityTokenReference str =
ws.createSTR_EncKeyRef("MyEncKey")
9.2.4.7 汎用トークンの参照STRの作成
createSTRメソッドを使用するかわりに、次のように適切なvalueTypeとtokenTypeを使用して参照を直接作成することもできます。
WSSecurity ws = ... String uri = "#MyToken"; WSSReference ref = new WSSReference(doc, uri); ref.setValueType(valueType); // set an optional valueType WSSecurityTokenReference str = new WSSecurityTokenReference(doc); str.setTokenType(tokenType); // set an optional tokenType str.appendChild(ref);
9.2.4.8 キー識別子STRの作成
KeyIdentifierは、assertionID (SAMLトークンの場合)やSubject Key Identifier (X509トークンの場合)など、トークンの固有プロパティを使用するセキュリティ・トークンを参照する別の方法です。
KeyIdentifersは、トークン自身が文書内に存在しない場合に多く使用されます。たとえば、受信メッセージはX509Certで暗号化できますが、メッセージには、そのX509Certを格納するかわりに、SubjectKeyIdentifierの形式でヒントのみを格納できます。
9.2.4.9 X509トークンのKeyIdentifier STRの作成
X509トークンを識別するには、次の3つの方法があります。
- 発行者のシリアル: 発行者のDNと証明書のシリアル番号の組合せ
- サブジェクト・キー識別子: 証明書のサブジェクト・キー識別子
- サムプリントSHA1: 証明書のSHA1
X509Certificate cert = ... WSSecurity ws = ... WSSecurityTokenReference str = ws.createSTR_X509_IssuerSerial(cert); // alternatively use ws.createSTR_X509_SKI(cert) // or ws. createSTR_X509_ThumbprintSHA1(cert)
9.2.4.10 KerberosトークンのKeyIdentifier STRの作成
Kerberosトークンは、AP_REQパケットのSHA1またはGSSでラップされたAP_REQパケットのSHA1で識別できます。
byte ap_req[] = ... WSSecurity ws = ... String valueType = WSSURI.vt_GSSKerberosv5; WSSecurityTokenReference str = ws.createSTR_KerberosKeyIdSHA1(ap_req, valueType);
9.2.4.11 SAMLアサーション・トークンのKeyIdentifier STRの作成
SAMLアサーションはアサーションIDで識別できます。
ローカルSAML 1.1アサーションでは、次を使用します。
WSSecurity.createSTR_SAML_AssertionIdv11(byte assertionId[])
リモートSAML 1.1アサーションでは、次を使用します。
createSTR_SAML_AssertionIdv11( byte assertionId[], AuthorityBinding authorityBinding)
ローカルSAML 2.0アサーションでは、次を使用します。
createSTR_SAML_AssertionIdv20(byte assertionId[])
リモートSAML 2.0アサーションでは、次のように参照URIを使用します。
createSTR_SAML_Assertion_Ref20("MySAMLAssertion")
9.2.4.12 EncryptedKeyのKeyIdentifier STRの作成
リモートで暗号化されたキーは、そのキーのSHA1ハッシュで識別できます。KeyIdentifierを作成するには、次の関数を使用します。
createSTR_EncKeySHA1(byte sha1[])
9.2.5 署名と検証
9.2.5.1 SOAPメッセージの署名
SOAPメッセージに署名するには、次のステップに従います。
- 署名対象のデータを指定する方法を決定します。最も一般的なメカニズムはIDを使用することですが、IDを使用するかわりにXPath式を使用することもできます。
- 追加の変換を決定します。排他的c14nとSTR変換は、追加可能な一般的な変換です。
- 署名キーを決定します。対称キーを使用するHMAC署名またはRSA/DSA署名のいずれかを実行できます。
- この署名キーを受信者に示す方法を決定します。この場合は通常、前述のSTRを作成する必要があります。
9.2.5.1.1 要素へのIDの追加
IDをDOM要素に追加することができます。
次の関数を使用します。
WSSUtils.addWsuIdToElement(String id, Element element)
これにより、署名対象の要素にwsu:Idを追加します。このメカニズムを使用すると、IDを追加して、DOM要素、またはDOM要素からも導出されるSAAJオブジェクトを正規化できます。
wsuネームスペースの接頭辞を宣言する必要があります。たとえば、次のようにSOAPエンベロープ・レベルで宣言できます。
SOAPEnvelope env = ...
env.addNamespaceDeclaration("wsu" , WSSURI.ns_wsu);
添付ファイルに署名するには、各添付ファイルにContentIdを割り当てる必要があります。この場合は、次のメソッドを使用する必要があります。
setContentId(String contentId)
このメソッドは、SAAJ AttachmentPartオブジェクトの一部です。
9.2.5.1.2 WSSignatureParamsオブジェクトの作成
WSSSignatureParamsオブジェクトは、すべての署名パラメータを使用して作成する必要があります。
最初のWSSignatureParamsオブジェクトを作成するには、次のコンストラクタを使用します。HMAC署名を使用する場合は、hmacKeyに値を渡し、signingKeyにnullを渡します。非対称署名を使用するには、signingKeyに値を渡し、hmacKeyにnullを渡します。
WSSignatureParams(byte[] hmacKey, PrivateKey signingKey);
このコストラクタは、c14nMethod=excC14N、digestMethod=SHA1、signMethod=hmacSHA/rsaSHA1/dsaSHA1(キーに応じて)を前提とします。異なるアルゴリズムが必要な場合は、次のsetterを使用して設定します。
setDigestMethod(String digestMethod) setSignMethod(String signMethod) setC14nMethod(String method)
前に作成したSTRをこのオブジェクトに設定する必要もあります。STRを設定するには、setKeyInfoDataを使用します。
setKeyInfoData(KeyInfoData keyInfoData)
添付ファイルに署名する場合は、このWSSignatureParamsオブジェクトにSOAPMessageを設定し、対応する添付ファイルを特定してcid参照を解決できるようにします。
setSOAPMessage(SOAPMessage msg)
9.2.5.1.3 変換の指定
変換を指定するには、単純だが制限がある方法と、高度で柔軟な方法の2つの方法があります。
単純な方法では、次のパラメータをWSSignatureParamsに設定する必要があります。
setAttachmentContentOnly(boolean)
単純なモードでは、すべてのcid参照によってAttachmentContentOnly変換が自動的に取得されますが、setAttachmentContentOnly(false)をコールすると、cid参照によってAttachmentComplete変換が取得されます。
· setUsingSTRTransform(boolean)
これをtrueに設定すると、各参照がSTRを指しているかどうかチェックされ、STRを指している場合は、該当の参照にSTRTransformが追加されます。STRTransformが追加されるのは、参照がSTRを直接指している場合のみで、参照がSTRの祖先を指している場合は追加されないことに注意してください。
· setC14Nmethod(String)
このパラメータは、デフォルトで排他的c14nに設定され、各参照の正規化メソッドとSignedInfoセクションの正規化メソッドの両方を指定します。
· setUsingDecryptTransfom(boolean)
復号化変換を追加する場合は、これをtrueに設定します。
9.2.5.1.4 WSSecurity.signメソッドのコール
最後に、WSSecurityの次のメソッドをコールし、実際の署名を実行します。
XSSignature sign (String[] uris, WSSignatureParams sigParams, XSAlgorithmIdentifier[][] trans)
このメソッドでは、<Signature>要素を作成して、各参照のダイジェストを計算し、最後に署名を計算します。
urisは署名対象のIDの配列です。この配列の要素ごとに、個別の<Reference>が作成されます。
前述のように、変換を指定するには2つの方法がありますが、単純な方法では、変換をnullにする必要があり、変換情報は前述の様々なsetメソッド(WSSignatureParams内)で指定されます。高度な方法では、参照ごとに変換パラメータですべての変換を明示的に指定する、つまり、trans.lengthとuris.lengthが等しくなるようにする必要があります。
9.2.5.2 SOAPメッセージの検証
署名を検証する場合は、最初に<wsse:Security>ヘッダーで署名要素を特定する必要があります。この場合は、次のメソッドを使用できます。
WSSecurity ws = ... List<XSSignature>sigs = ws.getSignatures();
このメソッドでは、DOMツリーを検索して、<dsig:Signature>である<wsse:Security>の直接の子をすべて特定し、これらの要素ごとにXSSignatureラッパー・オブジェクトを作成して返します。(ネームスペースの接頭辞にはwsseとdsigを使用する必要がないことに注意)
検証キーがすでにある場合は、次のメソッドをコールし、hmacKey(HMAC署名の場合)またはsigningKey(非対称キーの署名の場合)のいずれかを渡します。SOAPMessageが必要になるのは、添付ファイルが署名される場合のみです。
XSSignature sig = sigs[0]; byte [] hmacKey = ... PublicKey signingKey = ... ; // Need either hmacKey of signingKey SOAPMessage msg = null; // needed only for attachments boolean res = WSSecurity.verify(sig, byte[] hmacKey, signingKey, msg);
ただし、検証キーがない場合は、STRキー識別子を解決するために、次のコールバックを設定する必要があります。通常、STRキー識別子は文書外部のトークンの参照になるため、Oracle Security Developer Toolsでは、これらのコールバックを明示的に設定しないかぎり、これらのトークンを特定することはできません。
表9-3 STRキー識別子を解決するためのコールバック
| トークンのタイプ | 実装インタフェースと登録 | 注意 |
|---|---|---|
|
ユーザー名トークン |
インタフェース: PasswordRetriever
登録: UsernameToken.addPasswordRetriever |
このコールバックでは、UsernameTokenの参照STRを解決します。 getPassword()コールバックでは、ユーザーに対応するパスワードを返します。 この秘密キーは、パスワード、反復カウントおよびsaltから導出されます。 login()コールバックとlogout()コールバックは使用されません。 |
|
ユーザー名トークン |
インタフェース: KeyDerivator 登録: UsernameToken.addKeyDerivator |
このコールバックもUsernameTokenの参照STRを解決します。独自のキー導出アルゴリズムを使用する場合に使用します。resolve()コールバックでは、キーを導出して返します。 |
|
X509 |
インタフェース: X509KeyIdentifierResolver 登録: X509KeyIdentifier.addResolver |
このコールバックでは、サムプリントとSKIキー識別子のSTRを解決します。 証明書を返すにはresolve()コールバックを実装し、秘密キーを返すにはgetPrivateKey()コールバックを実装します。 注意: 秘密キーは検証には不要ですが、復号化には必要です。 証明書の配列がある場合は、X509KeyIdentifier.matches()メソッドを使用し、 渡したX509 KeyIdentifierに対して各証明書を照合します。 |
|
X509 |
インタフェース: X509IssuerSerialResolver 登録: X509IssuerSerial.addResolver |
このコールバックでは、発行者のシリアル・キー識別子のSTRを解決します。 前述の場合と同様に、resolve()コールバックとgetPrivateKey()コールバックを実装します。 |
|
Kerberos |
インタフェース: KerberosKeyIdentifierResolver
登録: KerberosKeyIdentifier.addResolver |
このコールバックでは、Kerberos STRを解決します。 resolve()およびresolveKey()メソッドを実装して、ap_reqパケットと、セッション・キー/サブキーを返します (これは、KeyIdentifierに存在するSHA1値に対応します)。
ap_reqパケットの配列がある場合は、その配列の各パケットのSHA1を計算し、 KerberosKeyIdentifier.getValue()によって返される値に一致するSHA1を持つものを検索します。 このap_reqパケットは、resolve()メソッドで返します。
resolveKey()メソッドの場合は、もう1つステップを実行して、 ap_Reqパケット内に存在する鍵を返します。この場合は、KerberosUtils.getSessionKey(Subject, byte[])メソッドを使用できます (これは、サブジェクトのキーを使用してap_reqパケットを復号化し、そこからセッション・キー/サブキーを抽出します)。 |
|
SAMLアサーション・バージョン1.1 |
インタフェース: SAMLAssertionKeyIdentifierResolver 登録: SAMLAssertionKeyIdentifier.addResolver |
このコールバックでは、SAMLアサーションのKeyIdentifier STRを解決します。 SAMLアサーションを返すにはresolve()メソッド、SAMLX509Certを返すにはgetPublicKey()メソッド、秘密キーを返すにはgetPrivateKey()メソッドを実装します。(注意: 秘密キーは復号化のみに必要で、検証には不要です。) |
|
SAMLアサーション・バージョン2.0 |
インタフェース: SAML2AssertionKeyIdentifierResolver 登録: SAML2AssertionKeyIdentifier.addResolver |
SAMLアサーション・バージョン1.1の注意事項を参照してください。 |
対称キーを使用するトークン(UserNameトークン、KerberosおよびEncryptedKey)の場合、この対称キーは文書内にないため、リゾルバを設定する必要があります。Oracle Security Developer Toolsでは、リゾルバを設定しないかぎり検証(復号化)はできません。
非対称キーを使用するトークン(SAMLアサーションとX509トークン)の場合は、Oracle Security Developer Toolsだけで証明書を特定できるため、直接のURI参照STRまたは埋込みのトークンを使用する場合は、リゾルバを設定する必要はありません。ただし、Oracle Security Developer Toolsでは、コールバックで証明書を検証していないかぎり、メッセージ内の証明書をむやみに使用しないため、CertificateValidatorコールバックを設定する必要があります。
関連項目:
すべてのリゾルバとCertificateValidatorを設定したら、次のメソッドを使用します。
SOAPMessage msg = null; // needed only for attachments boolean searchTokens = true; boolean res = WSSecurity.verify(sig, searchTokens, msg);
このメソッドでは、署名のKeyInfoを調べ、証明書を検索するか、適切なリゾルバをコールして署名用のキーを取得します。
WSSecurity.verifyAllメソッドを使用することもできます。このメソッドでは、署名を検索して1つずつ検証します。
9.2.5.3 署名の確認
署名確認の要素を構成して処理するには、WSSignatureConfirmationラッパー・クラスを使用します。
9.2.5.3.1 署名確認レスポンスの生成
レスポンス生成には、WSSecurityの次の関数を使用します。
List<WSSignatureConfirmation> createSignatureConfirmations(Document doc);
この関数では、現在のWSSecurity要素に存在するすべてのSignaturesを確認し、対応するSignatureConfirmation要素を新しい文書内に構成します。これらは、レスポンスのWSSecuirtyヘッダーに配置できます。
9.2.6 暗号化と復号化
EncryptedKeyを使用して(または使用せずに) SOAPメッセージを暗号化または復号化できます。
暗号化には、主に次の2つの方法があります。
EncryptedKeyを使用する方法: ランダム・セッション・キーで要素を暗号化して、このセッション・キーを<EncryptedKey>要素に暗号化し、この要素を<wsse:Security>ヘッダーに配置します。EncryptedKeyを使用しない方法: 各要素で異なる可能性のある既知の対称キーで要素を暗号化し、暗号化したこれらの各データ・セクションの参照で<ReferenceList>要素を構成し、<ReferenceList>を<wsse:Security>ヘッダーに配置します。
注意:
正規のDOM要素を暗号化するのが標準的な技法ですが、SOAPヘッダー、SOAP本文および添付ファイルを暗号化することもできます。これらのオブジェクトを暗号化する場合は、後述するように特に注意が必要です。
9.2.6.1 EncryptedKeyを使用したSOAPメッセージの暗号化
EncryptedKeyによりSOAPメッセージを暗号化できます。
次のように、このランダム・セッション・キーの暗号化に使用するキーを最初に決定し、受信者がこの復号化キーの特定に使用する情報を使用してSTRを作成します。
Key keyEncKey = ... ; WSSecurityTokenReference str = ...
次の情報を使用してWSSEncryptionParamsを作成します。
// Choose a data encryption algorithm - say AES 128 String dataEncAlg = XMLURI.alg_aes128_CBC; // Either generate a random session key yourself, or set this to // null to indicate that OSDT should generate it SecretKey dataEncKey = null; // Depending on the KeyEncryptionKey that you have chosen choose // either an RSA key wrap or a symmetric key wrap String keyEncAlg = XMLURI.alg_rsaOAEP_MGF1; // Now put all this information into a WSSEncryptionParams WSSEncryptionParams eParam = new WSSEncryptionParams( dataEncAlg, dataEncKey, keyEncAlg, keyEncKey, str);
次のように、DOM要素、SOAPヘッダー、SOAP本文またはAttachmentPartsを正規化します。
Element elem1 = ... // one object to be encrypted Element elem2 = … // another object to be encrypted ArrayList objectList[] = new ArrayList(); objectList.add(elem1); objectList.add(elem2);
次のように配列を2つ作成し、各オブジェクトを暗号化されたコンテンツのみにするかどうかを指定し、生成されるEncryptedDataオブジェクトに割り当てるIDを指定します。
注意:
SOAP本文は、このフラグで渡すものに関係なく、常に暗号化されたコンテンツのみになります。添付ファイルの場合、「コンテンツのみではない」は、コンテンツにmimeヘッダーを加えることを意味します。
// both these elements are not content only
boolean[] contentOnlys = { false, false };
// After encryption the EncryptedData elements will get these ids
String encDataIds[] = { "id1", "id2" };
最後に、次のようにencryptWithEncKeyメソッドをコールします。
WSSecurity ws = ... XEEncryptedKey encKey = ws.encryptWithEncKey(objectList, contentOnlys, encDataIds, eParam);
9.2.6.2 EncryptedKeyを使用しないSOAPメッセージの暗号化
EncryptedKeyを使用しない場合は、次のステップを使用します。
データの暗号化キーを決定します。すべてのEncryptedDataセクションで同じキーを使用できますが、セクションごとに異なるキーを使用することもできます。または、受信者がこの復号化キーの特定に使用する情報を使用してSTRを作成し、次のようにWSSEncryptionParamsオブジェクトに配置します。
SecretKey dataEncKey = ... ; // assuming 128 bit AES key String dataEncAlg = XMLURI.alg_aes128_CBC; WSSecurityTokenReference str = ... // Now put all this information into a WSSEncryptionParams WSSEncryptionParams eParam = new WSSEncryptionParams( dataEncAlg, dataEncKey, null, null, str);
前述の場合と同様、次のように暗号化対象の要素のリストと、関連するcontentOnlyとencDataIds配列を作成します。
Element elem1 = ... // one object to be encrypted
Element elem2 = … // another object to be encrypted
ArrayList objectList[] = new ArrayList();
objectList.add(elem1);
objectList.add(elem2);
// both these elements are not content only
boolean[] contentOnlys = { false, false };
// After encryption the EncryptedData elements will get these ids
String encDataIds[] = { "id1", "id2" };
最後に、次のようにencryptWithNoEncKeyメソッドをコールします。
WSSecurity ws = ...
XEEncryptedKey encKey = ws.encryptWithNoEncKey(objectList,
contentOnlys, encDataIds, new WSEncryptionParams[]{eParam, eParam});
この例では、両方の要素で同じencryptionParamsを使用しています。
9.2.6.3 SOAPヘッダーのEncryptedHeaderへの暗号化
コンテンツのみをfalseに設定して、SOAPヘッダー・ブロックで暗号化メソッドをコールすると、SOAPヘッダー・ブロック全体がEncryptedData要素に暗号化されます。この要素はEncryptedHeader要素内に配置され、元のSOAPヘッダー・ブロックを置き換えます。
mustUnderstand属性とactor属性が現在のwsse:Securityヘッダーからコピーされます。
9.2.6.4 EncryptedKeyを使用したSOAPメッセージの復号化
EncryptedKeyを使用してSOAPメッセージを復号化するには、次を使用します。
WSSecurity.decrypt(XEEncryptedKey, PrivateKey, SOAPMessage)
最初に、所定のPrivateKeyでEncryptedKeyを復号化して対称キーを取得し、この対称キーを使用して、EncryptedKey内のすべての参照を復号化します。
PrivateKeyがわからない場合は、次をコールします。
decrypt(XEEncryptedKey, SOAPMessage)
これにより、EncryptedKeyのKeyInfoが調べられ、登録されたコールバックがコールされて秘密キーが取得されます。
EncryptedKeyの復号化形式がわかっている場合は、次を使用します。
decrypt(XEEncryptedKey, SecretKey, SOAPMessage)
これにより、所定の対称キーを使用して、EncryptedKey内のすべての参照が復号化されます。
9.2.6.5 EncryptedKeyを使用しないSOAPメッセージの復号化
最上位レベルのReferenceListに示されたすべての要素(または添付ファイル)を復号化する場合は、次を使用します。
decrypt(XEReferenceList, SecretKey, SOAPMessage)
これにより、所定の対称キーを使用して、ReferenceList内のすべての参照が復号化されます。この関数は、すべての参照が同じキーで暗号化されていることを前提としています。
SecretKeyがわからない場合、またはすべての参照が同じキーで暗号化されていない場合は、SecretKeyにnullを入れてdecryptし、各EncrytedDataのKeyInfoを調べ、登録されたコールバックをコールして対称キーを取得します。
9.3 Web Services Securityの追加リソース
OASIS WSS SOAPメッセージ・セキュリティ仕様やOASIS WSSユーザー名トークン・プロファイル仕様などのOASIS仕様には、Webサービス・セキュリティの詳細が記載されています。
Webサービス・セキュリティの詳細は、次のリソースを参照してください。
-
OASIS WSS SOAPメッセージ・セキュリティ仕様
-
OASIS WSSユーザー名トークン・プロファイル仕様
-
OASIS WSS X.509証明書トークン・プロファイル仕様
-
OASIS WSS SAMLアサーション・トークン・プロファイル仕様
-
OASIS WSS SWAトークン・プロファイル仕様1.1
関連項目:
これらのドキュメントへのリンクは、「リファレンス」を参照してください。
9.4 Oracle Web Services SecurityのJava APIリファレンス
Oracle Web Services Security APIで利用可能なクラス、インタフェースおよびメソッドについては、『Oracle Fusion Middleware Oracle Security Developer Tools Java APIリファレンス』を参照してください。
このガイドには、次のリンクからアクセスできます。
Oracle Fusion Middleware Oracle Security Developer Tools Java APIリファレンス