4.2.7 鍵合意で作成した鍵を利用してデータを暗号化する
XMLデータの要素やコンテンツ,またはバイナリデータを暗号化する場合に使用する鍵や,鍵そのものを暗号化する場合に使用する鍵は,鍵合意で生成できます。鍵合意で鍵を生成するには,AgreementMethodクラスを使用します。この項では,Diffie-Hellman鍵合意アルゴリズムで生成した共通鍵を利用してデータを暗号化するアプリケーションの開発の流れを,コーディング例を示して説明します。
- 〈この項の構成〉
(1) Documentオブジェクトの生成
JAXPのDocumentBuilderを使用して暗号化したいXML文書を読み込み,Documentオブジェクトを取得します。Documentオブジェクトを取得するときに,名前空間が有効になるように設定してください。コーディングの例を次に示します。
DocumentBuilderFactory dbf =
DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
Document doc = dbf.newDocumentBuilder().parse(input);
(2) 暗号アルゴリズムの指定
XMLEncryptionFactoryクラスを使用してXMLEncryptionオブジェクトを生成し,暗号化に必要な暗号アルゴリズムを指定します。ここでは,暗号アルゴリズムにTripleDESを指定する場合のコーディングの例を示します。
XMLEncryptionFactory xef =
XMLEncryptionFactory.newInstance();
EncryptionMethod em = xef.newEncryptionMethod(
EncryptionMethod.URI_TRIPLEDES, null);
XMLEncryption xenc = xef.newXMLEncryption(em, null);
(3) 鍵合意による共通鍵の生成
XML Security - Coreでは,Diffie-Hellman鍵合意アルゴリズムを利用して暗号化に必要な共通鍵を生成します。ここでは,次の三つの処理について,コーディング例を示して説明します。
-
AgreementMethodオブジェクトの生成
-
鍵合意のコンテキストの設定
-
共通鍵の作成
- 参考
-
ここでは,KA-Nonce要素,OriginatorKeyInfo要素,またはRecipientKeyInfo要素は指定しない場合の例を説明しますが,必要に応じてこれらの要素を指定することもできます。
(a) AgreementMethodオブジェクトの生成
Diffie-Hellman鍵合意アルゴリズムで鍵を生成するには,まずDHKeyAgreementParamsオブジェクトを生成し,生成したDHKeyAgreementParamsオブジェクトを引数にしてKeyInfoFactoryクラスでAgreementMethodオブジェクトを生成します。コーディングの例を次に示します。
KeyInfoFactory kif = xef.getKeyInfoFactory();
DHKeyAgreementParams kap = new DHKeyAgreementParams(null,
xef.newDigestMethod(DigestMethod.URI_SHA1, null),
null, null);
AgreementMethod am =
kif.newAgreementMethod(AgreementMethod.URI_DH,kap);(4) 暗号データの生成
暗号データを生成する前に,コンテキストおよび暗号化対象を指定します。ここでは,次の三つの処理について,コーディング例を示して説明します。
-
コンテキストの設定
-
暗号化対象の指定
-
暗号データの生成
(a) コンテキストの設定
データの暗号化に必要なコンテキストを設定します。鍵リゾルバを使用して,鍵合意で生成した共通鍵をコンテキストに設定します。コンテキストの処理モードは,「暗号化」を指定してください。コーディングの例を次に示します。
XMLSecurityContext context = new XMLSecurityContext(
XMLSecurityContext.Mode.ENCRYPT, doc);
context.setKeyResolver(new AdhocKeyResolver(key));(5) 暗号構文の構築
XMLEncryptionFactoryクラスを使用して,EncryptedData要素以下の構文に対応するオブジェクトを生成します。この場合,KeyInfo要素にはAgreementMethodクラスを指定します。また,CipherValue要素を使用して「(4)(c) 暗号データの生成」で計算した暗号値を設定します。最後に,EncryptedDataクラスのreplaceメソッドを使用して,「(4)(b) 暗号化対象の指定」で指定した部分をEncryptedData要素に置き換えます。コーディングの例を次に示します。
CipherData cd = xef.newCipherData(xef.newCipherValue(
encrypted.getAsByteArray()));
KeyInfo ki = kif.newKeyInfo(Collections.singletonList(am));
EncryptedData ed = xef.newEncryptedData(em, ki, cd, null);
ed.setType(EncryptedData.URI_TYPE_ELEMENT);
ed.replace(context, toBeEncrypted);
(6) 暗号データの出力
XMLSerializerクラスを使用して,暗号化したい部分をEncryptedData要素に置き換えた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();