XMLデジタル署名API

概要およびチュートリアル

目次

Java XMLデジタル署名API

パッケージ階層

サービス・プロバイダ

XML署名について

XML署名の例

XMLデジタル署名APIの例

検証の例

XML署名の検証

署名を含むドキュメントのインスタンス化

検証する署名要素の指定

検証コンテキストの作成

XML署名の非整列化

XML署名の検証

XML署名の検証に失敗した場合

KeySelectorの使用

genenvelopedの例

XML署名の生成

署名するドキュメントのインスタンス化

公開鍵のペアの作成

署名コンテキストの作成

XML署名の構築

XML署名の生成

生成されるドキュメントの印刷または表示


Java XMLデジタル署名API

Java XMLデジタル署名APIは、XML署名を生成および検証するための標準のJava APIです。このAPIは、Java Community ProcessのもとでJSR 105として定義されました(http://jcp.org/en/jsr/detail?id=105を参照)。

XML署名は、任意のタイプのデータ(XMLまたはバイナリ)に適用できます(http://www.w3.org/TR/xmldsig-core/を参照)。結果の署名は、XMLで表されます。XML署名は、データを保護するために使用でき、データの整合性、メッセージ認証、および署名者認証を提供します。

このドキュメントでは、XML署名とXMLデジタル署名APIの概要を説明したあとで、APIを使用してXML署名を検証および生成する方法を示す2つの例について説明します。このドキュメントは、読者に暗号化およびデジタル署名の基本的な知識があることを前提としています。

APIは、「XML-Signature Syntax and Processing」でのW3C勧告の必須機能または推奨機能をすべてサポートするように設計されています。APIは拡張可能およびプラガブルであり、Java暗号化サービス・プロバイダ・アーキテクチャに基づいてます。APIは、次の2種類の開発者向けに設計されています。

  • XMLデジタル署名APIを使用してXML署名を生成および検証する開発者
  • XMLデジタル署名APIの固定実装を作成し、JCAプロバイダの暗号化サービスとして登録する開発者

パッケージ階層

次に示す6個のパッケージが、XMLデジタル署名APIを構成します。

  • javax.xml.crypto
  • javax.xml.crypto.dsig
  • javax.xml.crypto.dsig.keyinfo
  • javax.xml.crypto.dsig.spec
  • javax.xml.crypto.dom
  • javax.xml.crypto.dsig.dom

javax.xml.cryptoパッケージには、XML署名の生成やXMLデータの暗号化など、XML暗号化操作を行う場合に使用する共通クラスが含まれています。このパッケージで注意すべき2つのクラスのうちの1つはKeySelectorクラスで、開発者は、KeyInfoオブジェクトに含まれる情報を使用して鍵を見つけてオプションで検証する実装を提供できます。もう1つのクラスはURIDereferencerクラスで、開発者は、実装を間接参照する独自のURIを作成および指定できます。

javax.xml.crypto.dsigパッケージには、W3C XMLデジタル署名仕様で定義されているコア要素を表すインタフェースが含まれています。もっとも重要なのはXMLSignatureクラスです。このクラスを使用すると、XMLデジタル署名の署名および検証を行うことができます。XML署名構造または要素のほとんどは、対応するインタフェースによって表されます(KeyInfo構造を除く。これは独自のパッケージに含まれており、次の段落で説明します)。これらのインタフェースには、SignedInfoCanonicalizationMethodSignatureMethodReferenceTransformDigestMethodXMLObjectManifestSignaturePropertyおよびSignaturePropertiesが含まれます。XMLSignatureFactoryクラスは、これらのインタフェースを実装するオブジェクトを作成する場合に使用する抽象ファクトリです。

javax.xml.crypto.dsig.keyinfoパッケージには、W3C XMLデジタル署名勧告で定義されているほとんどのKeyInfo構造を表すインタフェースが含まれており、KeyInfoKeyNameKeyValueX509DataX509IssuerSerialRetrievalMethodおよびPGPDataが含まれます。KeyInfoFactoryクラスは、これらのインタフェースを実装するオブジェクトを作成する場合に使用する抽象ファクトリです。

javax.xml.crypto.dsig.specパッケージには、ダイジェスト、署名、変換、またはXML署名の処理で使用される正規化アルゴリズム用の入力パラメータを表すインタフェースおよびクラスが含まれています。

最後に、javax.xml.crypto.domおよびjavax.xml.crypto.dsig.domパッケージには、javax.xml.cryptoおよびjavax.xml.crypto.dsigパッケージ用のDOM固有のクラスが含まれています。DOMベースのXMLSignatureFactoryまたはKeyInfoFactory実装を作成または使用する開発者およびユーザーのみが、これらのパッケージを直接使用する必要があります。

サービス・プロバイダ

JSR 105暗号化サービスは、XMLSignatureFactoryおよびKeyInfoFactory抽象クラスの固定実装であり、XML署名やKeyInfo構造を解析、生成、および検証するオブジェクトやアルゴリズムを作成します。XMLSignatureFactoryの固定実装は、XML署名についてW3C勧告で指定されているように、必須アルゴリズムそれぞれをサポートする必要があります。オプションで、W3C勧告またはその他の仕様で定義されているように、その他のアルゴリズムをサポートできます。

JSR 105は、JCAプロバイダ・モデルを使用してXMLSignatureFactoryおよびKeyInfoFactory実装の登録とロードを行います。

固定実装XMLSignatureFactoryまたはKeyInfoFactoryはそれぞれ、XML署名やKeyInfo構造を解析および生成するときに実装によって内部で使用されるXML処理メカニズムを識別する特定の「XMLメカニズム・タイプ」をサポートしています。このJSRは、1つの標準形式であるDOMをサポートします。Java SEにバンドルされているXMLデジタル署名プロバイダ実装は、DOMメカニズムをサポートします。JDOMなどの新しい標準形式のサポートが、将来的に追加される可能性があります。

XMLデジタル署名API実装は、java.security.Signaturejava.security.MessageDigestなど、基盤となるJCAエンジン・クラスを使用して暗号化操作を実行するようにしてください。

XMLSignatureFactoryおよびKeyInfoFactoryクラス以外に、JSR 105は、変換および正規化アルゴリズム用のサービス・プロバイダ・インタフェースもサポートしています。TransformServiceクラスを使用すると、特定のXMLメカニズム・タイプ用の固有の変換または正規化アルゴリズムの実装を開発およびプラグインすることができます。TransformServiceクラスは、実装を登録およびロードするときに標準JCAプロバイダ・モデルを使用します。各JSR 105実装は、TransformServiceクラスを使用して、生成または検証するXML署名内の変換および正規化アルゴリズムをサポートするプロバイダを見つけるようにしてください。

XML署名について

XML署名を使用すると、XMLかバイナリかにかかわらず、任意のデータに署名できます。データは1つ以上のReference要素内のURIによって識別されます。XML署名は分離、内包または包含の3つの形式のうち、1つ以上の形式で記述されます。分離署名は外部、つまり署名要素自体の外にあるデータに対するものです。内包署名は署名要素の内側にあるデータに対する署名です。包含署名は署名対象のデータ内に含まれる署名です。

XML署名の例

XML署名の内容を説明するもっとも簡単な方法は、実際のサンプルを示し、各コンポーネントについて詳細に説明することです。次に、XMLドキュメントの内容に対して生成される包含XML署名の例を示します。署名される前のドキュメントの内容は、次のとおりです。

<Envelope xmlns="urn:envelope">
</Envelope> 

結果の包含XML署名は次のとおりです。読みやすくするために、インデントおよび形式設定されています。

<?xml version="1.0" encoding="UTF-8"?>
<Envelope xmlns="urn:envelope">
  <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
    <SignedInfo>
      <CanonicalizationMethod 
        Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments"/>
      <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#dsa-sha1"/>
      <Reference URI="">
        <Transforms>
          <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
        </Transforms>
        <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
        <DigestValue>uooqbWYa5VCqcJCbuymBKqm17vY=</DigestValue>
      </Reference>
    </SignedInfo>
    <SignatureValue>
      KedJuTob5gtvYx9qM3k3gm7kbLBwVbEQRl26S2tmXjqNND7MRGtoew==
    </SignatureValue>
    <KeyInfo>
      <KeyValue>
        <DSAKeyValue>
          <P>
            /KaCzo4Syrom78z3EQ5SbbB4sF7ey80etKII864WF64B81uRpH5t9jQTxe
            Eu0ImbzRMqzVDZkVG9xD7nN1kuFw==
          </P>
          <Q>li7dzDacuo67Jg7mtqEm2TRuOMU=</Q>
          <G>
            Z4Rxsnqc9E7pGknFFH2xqaryRPBaQ01khpMdLRQnG541Awtx/
            XPaF5Bpsy4pNWMOHCBiNU0NogpsQW5QvnlMpA==
          </G>
          <Y>
            qV38IqrWJG0V/mZQvRVi1OHw9Zj84nDC4jO8P0axi1gb6d+475yhMjSc/
            BrIVC58W3ydbkK+Ri4OKbaRZlYeRA==
          </Y>
        </DSAKeyValue>
      </KeyValue>
    </KeyInfo>
  </Signature>
</Envelope> 

Signature要素は署名対象の内容に挿入されており、それによって包含署名になっています。必須のSignedInfo要素には、実際に署名される次の情報が含まれています。

<SignedInfo>
  <CanonicalizationMethod 
    Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments"/>
  <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#dsa-sha1"/>
  <Reference URI="">
    <Transforms>
      <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
    </Transforms>
    <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
    <DigestValue>uooqbWYa5VCqcJCbuymBKqm17vY=</DigestValue>
  </Reference>
</SignedInfo> 

必須のCanonicalizationMethod要素は、署名または検証の前にSignedInfo要素を正規化するために使用されるアルゴリズムを定義します。正規化とは、そのデータに対する署名を無効化する可能性がある変更を考慮するために、XMLコンテンツを正規形に変換する処理のことを意味します。正規化は、XMLの性質および異なるプロセッサと中間的存在による解析のために必要です。正規化により、署名が無効になっても署名されたデータが論理的に同等であるようにデータを変更できます。

必須のSignatureMethod要素は、署名の生成に使用されるデジタル署名アルゴリズムを定義します。この場合は、SHA-1を使用するDSAです。

1つ以上のReference要素が、ダイジェストされるデータを識別します。各Reference要素は、URIによってデータを識別します。この例では、URIの値は空の文字列("")で、これはドキュメントのルートを示します。オプションのTransforms要素には、1つ以上のTransform要素のリストが含まれており、それぞれがダイジェスト前のデータの変換に使用される変換アルゴリズムを記述します。この例では、包含変換アルゴリズムのTransform要素が1つあります。包含変換は、署名値を計算する前に署名要素自体が削除されるようにするために、包含署名に必要です。必須のDigestMethod要素は、データのダイジェストに使用されるアルゴリズムを定義します。この場合は、SHA1です。最後に、必須のDigestValue要素には、実際のBase64でエンコードされたダイジェスト値が含まれています。

必須のSignatureValue要素には、SignedInfo要素に対する署名のBase64でエンコードされた署名値が含まれています。

オプションのKeyInfo要素には、署名の検証に必要な鍵に関する情報が含まれています。

<KeyInfo>
  <KeyValue>
    <DSAKeyValue>
      <P>
        /KaCzo4Syrom78z3EQ5SbbB4sF7ey80etKII864WF64B81uRpH5t9jQTxe
        Eu0ImbzRMqzVDZkVG9xD7nN1kuFw==
      </P>
      <Q>li7dzDacuo67Jg7mtqEm2TRuOMU=</Q>
      <G>
        Z4Rxsnqc9E7pGknFFH2xqaryRPBaQ01khpMdLRQnG541Awtx/
        XPaF5Bpsy4pNWMOHCBiNU0NogpsQW5QvnlMpA==
      </G>
      <Y>
        qV38IqrWJG0V/mZQvRVi1OHw9Zj84nDC4jO8P0axi1gb6d+475yhMjSc/
        BrIVC58W3ydbkK+Ri4OKbaRZlYeRA==
      </Y>
    </DSAKeyValue>
  </KeyValue>
</KeyInfo> 

このKeyInfo要素にはKeyValue 要素が含まれています。この要素には、署名の検証に必要な公開鍵で構成されるDSAKeyValue要素が含まれています。KeyInfoには、X.509証明書およびPGP鍵識別子など、様々な内容を含めることができます。様々なKeyInfoタイプの詳細は、XML署名勧告のKeyInfoセクションを参照してください。

XMLデジタル署名APIの例

次のセクションでは、XMLデジタル署名APIを使用する方法を示す2つの例について説明します。

  • 検証の例
  • 署名の例

検証の例

このセクションで示すコードは、Validate.javaファイルにあります。このファイルは docs/technotes/guides/security/xmldsigディレクトリにあります。処理のもとになるファイルenvelopedSignature.xmlは、同じディレクトリ内にあります。

この例をコンパイルして実行するには、docs/technotes/guides/security/xmldsigディレクトリから次のコマンドを実行します。

$javac Validate.java
$java Validate signature.xml

サンプル・プログラムは現在の作業ディレクトリ内のファイルsignature.xmlの署名を検証します。

XML署名の検証

この例では、JSR 105 APIを使用してXML署名を検証する方法を示します。この例はDOM (Document Object Model)を使用して、署名要素を含むXMLドキュメントおよびJSR 105 DOM実装を解析し、署名を検証します。

署名を含むドキュメントのインスタンス化

最初に、JAXP DocumentBuilderFactoryを使用して、署名を含むXMLドキュメントを解析します。アプリケーションは、次のコード行を呼び出すことによって、DocumentBuilderFactoryのデフォルト実装を取得します。

DocumentBuilderFactory dbf = 
  DocumentBuilderFactory.newInstance(); 

ファクトリ名前空間認識も作成します。

dbf.setNamespaceAware(true); 

次に、このファクトリを使用してDocumentBuilderのインスタンスを取得します。これはドキュメントの解析で使用されます。

DocumentBuilder builder = dbf.newDocumentBuilder();  
Document doc = builder.parse(new FileInputStream(argv[0])); 

検証する署名要素の指定

ドキュメントに複数含まれている場合もあるため、検証するSignature要素を指定する必要があります。DOMメソッドDocument.getElementsByTagNameNSを使用して、次に示すように、Signature要素のXML署名名前空間URIおよびタグ名をメソッドに渡します。

NodeList nl = doc.getElementsByTagNameNS
  (XMLSignature.XMLNS, "Signature");
if (nl.getLength() == 0) {
  throw new Exception("Cannot find Signature element");
} 

これは、ドキュメント内にあるすべてのSignature要素のリストを返します。この例ではSignature要素は1つのみです。

検証コンテキストの作成

署名を検証するための入力パラメータを含むXMLValidateContextインスタンスを作成します。DOMを使用しているため、DOMValidateContextインスタンス(XMLValidateContextのサブクラス)をインスタンス化し、2つのパラメータを渡します。2つのパラメータとは、KeyValueKeySelectorオブジェクトと、先に生成したNodeListの最初のエントリである、検証するSignature要素の参照です。

DOMValidateContext valContext = new DOMValidateContext
  (new KeyValueKeySelector(), nl.item(0)); 

KeyValueKeySelectorについては、「KeySelectorの使用」で詳細に説明します。

XML署名の非整列化

Signature要素の内容をXMLSignatureオブジェクトに抽出します。この処理は非整列化と呼ばれます。Signature要素はXMLSignatureFactoryオブジェクトを使用して非整列化されます。アプリケーションは次のコード行を呼び出すことによって、XMLSignatureFactoryのDOM実装を取得できます。

XMLSignatureFactory factory = 
  XMLSignatureFactory.getInstance("DOM"); 

次に、ファクトリのunmarshalXMLSignatureメソッドを呼び出してXMLSignatureオブジェクトを非整列化し、先に作成した検証コンテキストを渡します。


XMLSignature signature = 
  factory.unmarshalXMLSignature(valContext); 

XML署名の検証

これで、署名を検証する準備が整いました。XMLSignatureオブジェクトでvalidateメソッドを呼び出して、次に示すように検証コンテキストを渡します。

boolean coreValidity = signature.validate(valContext); 

W3C XML署名勧告コア検証規則に従って署名が正常に検証されると、validateメソッドは「true」を返します。それ以外の場合はfalseを返します。

XML署名の検証に失敗した場合

XMLSignature.validateメソッドがfalseを返した場合、失敗の原因の絞込みを試行できます。コアXML署名検証には、次の2つのフェーズがあります。

  • Signature validation (署名の暗号検証)
  • Reference validation (署名内の各参照のダイジェストの検証)

署名が有効になるには、それぞれのフェーズが成功する必要があります。署名の暗号化の検証が失敗したかどうかをチェックするために、次に示すようにステータスをチェックできます。

boolean sv = 
  signature.getSignatureValue().validate(valContext);
System.out.println("signature validation status: " + sv); 

次に示すように、参照に対して繰返し実行して、各参照の検証ステータスをチェックすることもできます。

Iterator i =
  signature.getSignedInfo().getReferences().iterator();
for (int j=0; i.hasNext(); j++) {
  boolean refValid = ((Reference) 
    i.next()).validate(valContext);
  System.out.println("ref["+j+"] validity status: " + 
    refValid);
} 

KeySelectorの使用

KeySelectorsは、XMLSignatureの検証に必要な鍵を見つけて選択するために使用されます。以前は、DOMValidateContextオブジェクトを作成したときは、KeySelectorオブジェクトを最初の引数として渡しました。

DOMValidateContext valContext = new DOMValidateContext
  (new KeyValueKeySelector(), nl.item(0)); 

また、署名の検証に必要な鍵がすでにわかっている場合は、PublicKeyを最初の引数として渡すこともできました。ただし、多くの場合はわかりません。

KeyValueKeySelectorは、抽象KeySelectorクラスの固定実装です。KeyValueKeySelector実装は、XMLSignatureKeyInfo要素のKeyValue要素に含まれるデータを使用して、適切な検証鍵を見つけようとします。鍵が信頼できるかどうかは判断しません。これは、単純なKeySelector実装であり、実際の使用というよりは説明のために設計されています。KeySelectorのより実用的な例は、KeyInfoに含まれるX509Data情報(X509SubjectName要素、X509IssuerSerial要素、X509SKI要素、X509Certificate要素など)に一致する信頼できる鍵でKeyStoreを検索する例です。

KeyValueKeySelectorの実装は、次のとおりです。

private static class KeyValueKeySelector extends KeySelector {

  public KeySelectorResult select(KeyInfo keyInfo,
      KeySelector.Purpose purpose,
      AlgorithmMethod method,
      XMLCryptoContext context)
    throws KeySelectorException {

    if (keyInfo == null) {
      throw new KeySelectorException("Null KeyInfo object!");
    }
    SignatureMethod sm = (SignatureMethod) method;
    List list = keyInfo.getContent();

    for (int i = 0; i < list.size(); i++) {
      XMLStructure xmlStructure = (XMLStructure) list.get(i);
      if (xmlStructure instanceof KeyValue) {
        PublicKey pk = null;
        try {
          pk = ((KeyValue)xmlStructure).getPublicKey();
        } catch (KeyException ke) {
          throw new KeySelectorException(ke);
        }
        // make sure algorithm is compatible with method
        if (algEquals(sm.getAlgorithm(), 
            pk.getAlgorithm())) {
          return new SimpleKeySelectorResult(pk);
        }
      }
    }
    throw new KeySelectorException("No KeyValue element 
found!");
  }

  static boolean algEquals(String algURI, String algName) {
    if (algName.equalsIgnoreCase("DSA") &&
        algURI.equalsIgnoreCase("http://www.w3.org/2009/xmldsig11#dsa-sha256")) {
      return true;
    } else if (algName.equalsIgnoreCase("RSA") &&
        algURI.equalsIgnoreCase("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256")) {
      return true;
    } else {
      return false;
    }
  }
} 

genenvelopedの例

このセクションで説明しているコードは、GenEnveloped.javaファイルにあります。このファイルは docs/technotes/guides/security/xmldsigディレクトリにあります。処理のもとになるファイルenvelope.xmlは、同じディレクトリ内にあります。このファイルは、ファイルenvelopedSignature.xmlを生成します。

このサンプルをコンパイルし、実行するには、 docs/technotes/guides/security/xmldsigディレクトリから、次のコマンドを実行します。

$ javac GenEnveloped.java
$ java GenEnveloped envelope.xml envelopedSignature.xml

サンプル・プログラムはファイルenvelope.xml内のドキュメントの包含署名を生成し、現在の作業ディレクトリ内のファイルenvelopedSignature.xmlに保存します。

XML署名の生成

この例では、XMLデジタル署名APIを使用してXML署名を生成する方法を示します。より具体的には、この例はXMLドキュメントの包含XML署名を生成します。包含署名とは、署名対象の内容に含まれる署名です。この例はDOM (Document Object Model)を使用して、署名対象のXMLドキュメントおよびJSR 105 DOM実装を解析し、結果の署名を生成します。

XML署名およびそのさまざまなコンポーネントの基本的な知識が、このセクションの理解に役立ちます。詳細は、http://www.w3.org/TR/xmldsig-core/を参照してください。

署名するドキュメントのインスタンス化

最初に、JAXP DocumentBuilderFactoryを使用して、署名するXMLドキュメントを解析します。アプリケーションは、次のコード行を呼び出すことによって、DocumentBuilderFactoryのデフォルト実装を取得します。

DocumentBuilderFactory dbf =
  DocumentBuilderFactory.newInstance(); 

ファクトリ名前空間認識も作成します。

dbf.setNamespaceAware(true); 

次に、このファクトリを使用してDocumentBuilderのインスタンスを取得します。これはドキュメントの解析で使用されます。

DocumentBuilder builder = dbf.newDocumentBuilder();  
Document doc = builder.parse(new FileInputStream(argv[0])); 

公開鍵のペアの作成

公開鍵のペアを生成します。あとの例では、非公開鍵を使用して署名を生成します。KeyPairGeneratorを使用して、鍵のペアを作成します。この例では、2048バイトの長さのDSA KeyPairを作成します。

KeyPairGenerator kpg = KeyPairGenerator.getInstance("DSA");
kpg.initialize(2048);
KeyPair kp = kpg.generateKeyPair(); 

実際には、非公開鍵は通常は以前に生成されて、関連する公開鍵証明書とともにKeyStoreファイルに保存されています。

署名コンテキストの作成

署名を生成するための入力パラメータを含む、XMLデジタル署名XMLSignContextを作成します。DOMを使用しているので、DOMSignContext (XMLSignContextのサブクラス)をインスタンス化し、2つのパラメータを渡します。パラメータは、ドキュメントの署名に使用される秘密鍵と署名対象のドキュメントのルートです。

DOMSignContext dsc = new DOMSignContext
  (kp.getPrivate(), doc.getDocumentElement()); 

XML署名の構築

Signature要素のさまざまな部分を組み合わせて、XMLSignatureオブジェクトにします。これらのオブジェクトはすべて、XMLSignatureFactoryオブジェクトを使用して、作成され組み合わせられます。アプリケーションは次のコード行を呼び出すことによって、XMLSignatureFactoryのDOM実装を取得します。

XMLSignatureFactory fac = 
  XMLSignatureFactory.getInstance("DOM"); 

次に示すように、さまざまなファクトリ・メソッドを呼び出してXMLSignatureオブジェクトのさまざまな部分を作成します。Referenceオブジェクトを作成して、そのオブジェクトに次のものを渡します。

  • 署名対象のオブジェクトのURI (ここでは、ドキュメントのルートを示すURI ""を指定)
  • DigestMethod (ここでは、SHA1を使用)
  • 1つのTransform、包含Transform (署名値の計算の前に署名自体が削除されるように、包含署名で必要)
Reference ref = fac.newReference
  ("", fac.newDigestMethod(DigestMethod.SHA256, null),
    Collections.singletonList
      (fac.newTransform(Transform.ENVELOPED,
        (TransformParameterSpec) null)), null, null); 

次に、SignedInfoオブジェクトを作成します。これは、次に示すように、実際に署名されるオブジェクトです。SignedInfoを作成するときは、次のものをパラメータとして渡します。

  • CanonicalizationMethod (ここでは、INCLUSIVEを使用してコメントを保持)
  • SignatureMethod (ここでは、DSAを使用)
  • Referencesのリスト(この場合は1つのみ)
SignedInfo si = fac.newSignedInfo
  (fac.newCanonicalizationMethod
    (CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS,
      (C14NMethodParameterSpec) null),
    fac.newSignatureMethod("http://www.w3.org/2009/xmldsig11#dsa-sha256", null),
    Collections.singletonList(ref)); 

次に、オプションのKeyInfoオブジェクトを作成します。このオブジェクトには、受け側が署名の検証に必要な鍵を見つけられるようにする情報が含まれています。この例では、公開鍵を含むKeyValueオブジェクトを追加します。KeyInfoおよびその様々なサブタイプを作成するには、KeyInfoFactoryオブジェクトを使用します。このオブジェクトは次に示すように、XMLSignatureFactorygetKeyInfoFactoryメソッドを呼び出すことによって取得できます。

KeyInfoFactory kif = fac.getKeyInfoFactory(); 

次に、KeyInfoFactoryを使用してKeyValueオブジェクトを作成し、KeyInfoオブジェクトに追加します。

KeyValue kv = kif.newKeyValue(kp.getPublic());
KeyInfo ki = kif.newKeyInfo(Collections.singletonList(kv)); 

最後に、XMLSignatureオブジェクトを作成し、先に作成したSignedInfoおよびKeyInfoオブジェクトをパラメータとして渡します。

XMLSignature signature = fac.newXMLSignature(si, ki); 

まだ実際には署名を生成していません。次のステップで生成します。

XML署名の生成

これで、署名を生成する準備が整いました。XMLSignatureオブジェクトでsignメソッドを呼び出して、次に示すように署名コンテキストを渡します。

signature.sign(dsc); 

これで、結果のドキュメントには署名が含まれています。署名は、ルート要素の最後の子要素として挿入されました。

生成されるドキュメントの印刷または表示

次のコードを使用して、結果の署名済みドキュメントをファイルまたは標準出力に印刷できます。

OutputStream os;
if (args.length > 1) {
  os = new FileOutputStream(args[1]);
} else {
  os = System.out;
} 
TransformerFactory tf = TransformerFactory.newInstance();
Transformer trans = tf.newTransformer();
trans.transform(new DOMSource(doc), new StreamResult(os)); 


Copyright © 1993, 2020, Oracle and/or its affiliates. All rights reserved.