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><ds:Signature></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 + -
显示快捷键?