4.1.2 Enveloping署名を生成する
この項では,Enveloping署名を生成する場合の処理内容とコーディング例を説明します。
(1) XML署名文書のDocumentオブジェクトの生成
JAXPのDocumentBuilderクラスを使用して,署名対象のXML文書を読み込んで,署名を付与したい要素(署名対象)を取得します。このとき,名前空間が有効になるように設定してください。次に,Signature要素を文書要素とする署名文書を作成する準備として,新たに空のDocumentオブジェクトを生成します。また,Enveloping署名に署名対象を含めるために,生成したDocumentオブジェクトに署名対象をあらかじめインポートしておきます。コーディングの例を次に示します。
DocumentBuilderFactory dbf =
DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc0 = db.parse(input);
Element elem0 = doc0.getDocumentElement();
Document doc = db.newDocument();
Element elem = (Element) doc.importNode(elem0, true);
(2) XML署名構文の構築
XMLSignatureFactoryクラスを使用して,各要素に対応するオブジェクトを生成します。Enveloping署名では,署名対象をDOMNodeContainerオブジェクトでラップして,XMLObjectオブジェクトに設定します。
署名対象および各種アルゴリズムは,XML署名構文を構築するときに設定しておきます。ここでは,次の設定をする場合の例を説明します。なお,署名対象を指定するためのIdは「foo」とします。
-
署名対象:URI="#foo"
-
ダイジェストアルゴリズム:SHA1
-
変換アルゴリズム:なし
-
正規化アルゴリズム:コメントなしXML-C14N
-
署名アルゴリズム:RSAwithSHA1
XMLSignatureFactory xsf = XMLSignatureFactory.newInstance();
XMLObject obj = xsf.newXMLObject(Collections.singletonList(
new DOMNodeContainer(elem)));
obj.setId("foo");
Reference ref = xsf.newReference("#foo", xsf.newDigestMethod(
DigestMethod.URI_SHA1, null), null);
SignedInfo si =
xsf.newSignedInfo(xsf.newCanonicalizationMethod(
CanonicalizationMethod.URI_OMIT_COMMENTS, null),
xsf.newSignatureMethod(
SignatureMethod.URI_RSA_SHA1, null),
Collections.singletonList(ref));
XMLSignature sig = xsf.newXMLSignature(si, null,
Collections.singletonList(obj));
(3) XML署名データの生成
Enveloping署名データを生成するには,コンテキストおよび署名生成位置を指定する必要があります。ここでは,次の三つの処理について,コーディング例を示して説明します。
-
コンテキストの設定
-
ML署名を生成する位置の設定
-
XML署名データの生成
(a) コンテキストの設定
Enveloping署名データの生成に必要なコンテキストを設定します。署名に使用する鍵を使って鍵リゾルバを生成し,コンテキストに鍵リゾルバを設定します。コンテキストの処理モードは,「署名生成」を指定してください。コーディングの例を次に示します。
XMLSecurityContext context
= new XMLSecurityContext(
XMLSecurityContext.Mode.SIGN, doc);
context.setKeyResolver(
new AdhocKeyResolver(Utilities.getPrivateKey()));(4) XML署名文書の出力
XMLSerializerクラスを使用して,Signature要素を持つDocumentオブジェクトをXML形式で出力します。冗長な名前空間を省略し,Shift_JISで出力する場合のコーディングの例を次に示します。
XMLOutputFormat format = new XMLOutputFormat();
format.setOmitRedundantNamespaceDecls(true);
format.setEncoding("Shift_JIS");
OutputStream os = new BufferedOutputStream(
new FileOutputStream(output));
XMLSerializer xsr = new XMLSerializer(os, format);
xsr.serialize(doc);
os.close();