xmlsignature.java

来自「JAVA 所有包」· Java 代码 · 共 755 行 · 第 1/2 页

JAVA
755
字号
/* * Copyright  1999-2004 The Apache Software Foundation. * *  Licensed under the Apache License, Version 2.0 (the "License"); *  you may not use this file except in compliance with the License. *  You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * *  Unless required by applicable law or agreed to in writing, software *  distributed under the License is distributed on an "AS IS" BASIS, *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *  See the License for the specific language governing permissions and *  limitations under the License. * */package com.sun.org.apache.xml.internal.security.signature;import java.io.IOException;import java.io.OutputStream;import java.security.Key;import java.security.PublicKey;import java.security.cert.X509Certificate;import javax.crypto.SecretKey;import com.sun.org.apache.xml.internal.security.algorithms.SignatureAlgorithm;import com.sun.org.apache.xml.internal.security.c14n.CanonicalizationException;import com.sun.org.apache.xml.internal.security.c14n.Canonicalizer;import com.sun.org.apache.xml.internal.security.c14n.InvalidCanonicalizerException;import com.sun.org.apache.xml.internal.security.exceptions.Base64DecodingException;import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException;import com.sun.org.apache.xml.internal.security.keys.KeyInfo;import com.sun.org.apache.xml.internal.security.keys.content.X509Data;import com.sun.org.apache.xml.internal.security.transforms.Transforms;import com.sun.org.apache.xml.internal.security.utils.Base64;import com.sun.org.apache.xml.internal.security.utils.Constants;import com.sun.org.apache.xml.internal.security.utils.I18n;import com.sun.org.apache.xml.internal.security.utils.IdResolver;import com.sun.org.apache.xml.internal.security.utils.SignatureElementProxy;import com.sun.org.apache.xml.internal.security.utils.SignerOutputStream;import com.sun.org.apache.xml.internal.security.utils.UnsyncBufferedOutputStream;import com.sun.org.apache.xml.internal.security.utils.XMLUtils;import com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolver;import com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolverSpi;import org.w3c.dom.Document;import org.w3c.dom.Element;import org.w3c.dom.Node;import org.w3c.dom.Text;/** * Handles <code>&lt;ds:Signature&gt;</code> elements. * This is the main class that deals with creating and verifying signatures. * * <p>There are 2 types of constructors for this class. The ones that take a * document, baseURI and 1 or more Java Objects. This is mostly used for * signing purposes. * The other constructor is the one that takes a DOM Element and a BaseURI. * This is used mostly with for verifying, when you have a SignatureElement. * * There are a few different types of methods: * <ul><li>The addDocument* methods are used to add References with optional * transforms during signing. </li> * <li>addKeyInfo* methods are to add Certificates and Keys to the * KeyInfo tags during signing. </li> * <li>appendObject allows a user to add any XML Structure as an * ObjectContainer during signing.</li> * <li>sign and checkSignatureValue methods are used to sign and validate the * signature. </li></ul> * * @author $Author: raul $ */public final class XMLSignature extends SignatureElementProxy {   /** {@link java.util.logging} logging facility */   static java.util.logging.Logger log =         java.util.logging.Logger.getLogger(XMLSignature.class.getName());      //J-   /** MAC - Required HMAC-SHA1 */   public static final String ALGO_ID_MAC_HMAC_SHA1 = Constants.SignatureSpecNS + "hmac-sha1";   /** Signature - Required DSAwithSHA1 (DSS) */   public static final String ALGO_ID_SIGNATURE_DSA = Constants.SignatureSpecNS + "dsa-sha1";   /** Signature - Recommended RSAwithSHA1 */   public static final String ALGO_ID_SIGNATURE_RSA = Constants.SignatureSpecNS + "rsa-sha1";   /** Signature - Recommended RSAwithSHA1 */   public static final String ALGO_ID_SIGNATURE_RSA_SHA1 = Constants.SignatureSpecNS + "rsa-sha1";   /** Signature - NOT Recommended RSAwithMD5 */   public static final String ALGO_ID_SIGNATURE_NOT_RECOMMENDED_RSA_MD5 = Constants.MoreAlgorithmsSpecNS + "rsa-md5";   /** Signature - Optional RSAwithRIPEMD160 */   public static final String ALGO_ID_SIGNATURE_RSA_RIPEMD160 = Constants.MoreAlgorithmsSpecNS + "rsa-ripemd160";   /** Signature - Optional RSAwithSHA256 */   public static final String ALGO_ID_SIGNATURE_RSA_SHA256 = Constants.MoreAlgorithmsSpecNS + "rsa-sha256";   /** Signature - Optional RSAwithSHA384 */   public static final String ALGO_ID_SIGNATURE_RSA_SHA384 = Constants.MoreAlgorithmsSpecNS + "rsa-sha384";   /** Signature - Optional RSAwithSHA512 */   public static final String ALGO_ID_SIGNATURE_RSA_SHA512 = Constants.MoreAlgorithmsSpecNS + "rsa-sha512";   /** HMAC - NOT Recommended HMAC-MD5 */   public static final String ALGO_ID_MAC_HMAC_NOT_RECOMMENDED_MD5 = Constants.MoreAlgorithmsSpecNS + "hmac-md5";   /** HMAC - Optional HMAC-RIPEMD160 */   public static final String ALGO_ID_MAC_HMAC_RIPEMD160 = Constants.MoreAlgorithmsSpecNS + "hmac-ripemd160";   /** HMAC - Optional HMAC-SHA256 */   public static final String ALGO_ID_MAC_HMAC_SHA256 = Constants.MoreAlgorithmsSpecNS + "hmac-sha256";   /** HMAC - Optional HMAC-SHA284 */   public static final String ALGO_ID_MAC_HMAC_SHA384 = Constants.MoreAlgorithmsSpecNS + "hmac-sha384";   /** HMAC - Optional HMAC-SHA512 */   public static final String ALGO_ID_MAC_HMAC_SHA512 = Constants.MoreAlgorithmsSpecNS + "hmac-sha512";   //J+   /** ds:Signature.ds:SignedInfo element */   private SignedInfo _signedInfo = null;   /** ds:Signature.ds:KeyInfo */   private KeyInfo _keyInfo = null;   /**    * Checking the digests in References in a Signature are mandatory, but for    * References inside a Manifest it is application specific. This boolean is    * to indicate that the References inside Manifests should be validated.    */   private boolean _followManifestsDuringValidation = false;  /**    * This creates a new <CODE>ds:Signature</CODE> Element and adds an empty    * <CODE>ds:SignedInfo</CODE>.    * The <code>ds:SignedInfo</code> is initialized with the specified Signature    * algorithm and Canonicalizer.ALGO_ID_C14N_OMIT_COMMENTS which is REQUIRED    * by the spec. This method's main use is for creating a new signature.    *    * @param doc Document in which the signature will be appended after creation.    * @param BaseURI URI to be used as context for all relative URIs.    * @param SignatureMethodURI signature algorithm to use.    * @throws XMLSecurityException    */   public XMLSignature(Document doc, String BaseURI, String SignatureMethodURI)           throws XMLSecurityException {      this(doc, BaseURI, SignatureMethodURI, 0,           Canonicalizer.ALGO_ID_C14N_OMIT_COMMENTS);   }   /**    * Constructor XMLSignature    *    * @param doc    * @param BaseURI    * @param SignatureMethodURI the Signature method to be used.    * @param HMACOutputLength    * @throws XMLSecurityException    */   public XMLSignature(           Document doc, String BaseURI, String SignatureMethodURI, int HMACOutputLength)              throws XMLSecurityException {      this(doc, BaseURI, SignatureMethodURI, HMACOutputLength,           Canonicalizer.ALGO_ID_C14N_OMIT_COMMENTS);   }   /**    * Constructor XMLSignature    *    * @param doc    * @param BaseURI    * @param SignatureMethodURI the Signature method to be used.    * @param CanonicalizationMethodURI the canonicalization algorithm to be used to c14nize the SignedInfo element.    * @throws XMLSecurityException    */   public XMLSignature(           Document doc, String BaseURI, String SignatureMethodURI, String CanonicalizationMethodURI)              throws XMLSecurityException {      this(doc, BaseURI, SignatureMethodURI, 0, CanonicalizationMethodURI);   }   /**    * Constructor XMLSignature    *    * @param doc    * @param BaseURI    * @param SignatureMethodURI    * @param HMACOutputLength    * @param CanonicalizationMethodURI    * @throws XMLSecurityException    */   public XMLSignature(           Document doc, String BaseURI, String SignatureMethodURI, int HMACOutputLength, String CanonicalizationMethodURI)              throws XMLSecurityException {      super(doc);      XMLUtils.addReturnToElement(this._constructionElement);      this._baseURI = BaseURI;      this._signedInfo = new SignedInfo(this._doc, SignatureMethodURI,                                        HMACOutputLength,                                        CanonicalizationMethodURI);      this._constructionElement.appendChild(this._signedInfo.getElement());      XMLUtils.addReturnToElement(this._constructionElement);      // create an empty SignatureValue; this is filled by setSignatureValueElement      Element signatureValueElement =         XMLUtils.createElementInSignatureSpace(this._doc,                                                Constants._TAG_SIGNATUREVALUE);      this._constructionElement.appendChild(signatureValueElement);      XMLUtils.addReturnToElement(this._constructionElement);   }   /**    *  Creates a XMLSignature in a Document    * @param doc    * @param BaseURI    * @param SignatureMethodElem    * @param CanonicalizationMethodElem    * @throws XMLSecurityException    */   public XMLSignature(           Document doc, String BaseURI, Element SignatureMethodElem, Element CanonicalizationMethodElem)              throws XMLSecurityException {      super(doc);      XMLUtils.addReturnToElement(this._constructionElement);      this._baseURI = BaseURI;      this._signedInfo = new SignedInfo(this._doc, SignatureMethodElem, CanonicalizationMethodElem);      this._constructionElement.appendChild(this._signedInfo.getElement());      XMLUtils.addReturnToElement(this._constructionElement);      // create an empty SignatureValue; this is filled by setSignatureValueElement      Element signatureValueElement =         XMLUtils.createElementInSignatureSpace(this._doc,                                                Constants._TAG_SIGNATUREVALUE);      this._constructionElement.appendChild(signatureValueElement);      XMLUtils.addReturnToElement(this._constructionElement);   }   /**    * This will parse the element and construct the Java Objects.    * That will allow a user to validate the signature.    *    * @param element ds:Signature element that contains the whole signature    * @param BaseURI URI to be prepended to all relative URIs    * @throws XMLSecurityException    * @throws XMLSignatureException if the signature is badly formatted    */   public XMLSignature(Element element, String BaseURI)           throws XMLSignatureException, XMLSecurityException {      super(element, BaseURI);      // check out SignedInfo child      Element signedInfoElem = XMLUtils.selectDsNode(this._constructionElement.getFirstChild(),                                  Constants._TAG_SIGNEDINFO,0);      // check to see if it is there      if (signedInfoElem == null) {         Object exArgs[] = { Constants._TAG_SIGNEDINFO,                             Constants._TAG_SIGNATURE };         throw new XMLSignatureException("xml.WrongContent", exArgs);      }      // create a SignedInfo object from that element      this._signedInfo = new SignedInfo(signedInfoElem, BaseURI);      // check out SignatureValue child      Element signatureValueElement = XMLUtils.selectDsNode(this._constructionElement.getFirstChild(),                                         Constants._TAG_SIGNATUREVALUE,0);      // check to see if it exists      if (signatureValueElement == null) {         Object exArgs[] = { Constants._TAG_SIGNATUREVALUE,                             Constants._TAG_SIGNATURE };         throw new XMLSignatureException("xml.WrongContent", exArgs);      }      // <element ref="ds:KeyInfo" minOccurs="0"/>      Element keyInfoElem =XMLUtils.selectDsNode(this._constructionElement.getFirstChild(),                               Constants._TAG_KEYINFO,0);      // If it exists use it, but it's not mandatory      if (keyInfoElem != null) {         this._keyInfo = new KeyInfo(keyInfoElem, BaseURI);      }   }   /**    * Sets the <code>Id</code> attribute    *    * @param Id Id value to be used by the id attribute on the Signature Element    */   public void setId(String Id) {      if ((this._state == MODE_SIGN) && (Id != null)) {         this._constructionElement.setAttributeNS(null, Constants._ATT_ID, Id);         IdResolver.registerElementById(this._constructionElement, Id);      }   }   /**    * Returns the <code>Id</code> attribute    *    * @return the <code>Id</code> attribute    */   public String getId() {      return this._constructionElement.getAttributeNS(null, Constants._ATT_ID);   }   /**    * Returns the completely parsed <code>SignedInfo</code> object.    *    * @return the completely parsed <code>SignedInfo</code> object.    */   public SignedInfo getSignedInfo() {      return this._signedInfo;   }   /**    * Returns the octet value of the SignatureValue element.    * Throws an XMLSignatureException if it has no or wrong content.    *    * @return the value of the SignatureValue element.    * @throws XMLSignatureException If there is no content    */   public byte[] getSignatureValue() throws XMLSignatureException {      try {         Element signatureValueElem = XMLUtils.selectDsNode(this._constructionElement.getFirstChild(),                                         Constants._TAG_SIGNATUREVALUE,0);         byte[] signatureValue = Base64.decode(signatureValueElem);         return signatureValue;      } catch (Base64DecodingException ex) {         throw new XMLSignatureException("empty", ex);      }   }   /**    * Base64 encodes and sets the bytes as the content of the SignatureValue    * Node.    *    * @param bytes bytes to be used by SignatureValue before Base64 encoding    */   private void setSignatureValueElement(byte[] bytes)   {      if (this._state == MODE_SIGN) {         Element signatureValueElem = XMLUtils.selectDsNode(this._constructionElement.getFirstChild(),                                         Constants._TAG_SIGNATUREVALUE,0);         while (signatureValueElem.hasChildNodes()) {            signatureValueElem.removeChild(signatureValueElem.getFirstChild());         }         String base64codedValue = Base64.encode(bytes);         if (base64codedValue.length() > 76) {            base64codedValue = "\n" + base64codedValue + "\n";         }         Text t = this._doc.createTextNode(base64codedValue);         signatureValueElem.appendChild(t);      }   }   /**    * Returns the KeyInfo child. If we are in signing mode and the KeyInfo    * does not exist yet, it is created on demand and added to the Signature.    * <br>    * This allows to add arbitrary content to the KeyInfo during signing.    *

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?