xmlsignature.java

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

JAVA
755
字号
    * @return the KeyInfo object    */   public KeyInfo getKeyInfo() {      // check to see if we are signing and if we have to create a keyinfo      if ((this._state == MODE_SIGN) && (this._keyInfo == null)) {         // create the KeyInfo         this._keyInfo = new KeyInfo(this._doc);         // get the Element from KeyInfo         Element keyInfoElement = this._keyInfo.getElement();         Element firstObject=null;         Node sibling= this._constructionElement.getFirstChild();         firstObject = XMLUtils.selectDsNode(sibling,Constants._TAG_OBJECT,0);	   	                 if (firstObject != null) {               // add it before the object               this._constructionElement.insertBefore(keyInfoElement,                                                      firstObject);               this._constructionElement                  .insertBefore(this._doc.createTextNode("\n"), firstObject);            } else {               // add it as the last element to the signature               this._constructionElement.appendChild(keyInfoElement);               XMLUtils.addReturnToElement(this._constructionElement);            }               }      return this._keyInfo;   }   /**    * Appends an Object (not a <code>java.lang.Object</code> but an Object    * element) to the Signature. Please note that this is only possible    * when signing.    *    * @param object ds:Object to be appended.    * @throws XMLSignatureException When this object is used to verify.    */   public void appendObject(ObjectContainer object)           throws XMLSignatureException {      try {         if (this._state != MODE_SIGN) {            throw new XMLSignatureException(               "signature.operationOnlyBeforeSign");         }         this._constructionElement.appendChild(object.getElement());         XMLUtils.addReturnToElement(this._constructionElement);      } catch (XMLSecurityException ex) {         throw new XMLSignatureException("empty", ex);      }   }   /**    * Returns the <code>i<code>th <code>ds:Object</code> child of the signature    * or null if no such <code>ds:Object</code> element exists.    *    * @param i    * @return the <code>i<code>th <code>ds:Object</code> child of the signature or null if no such <code>ds:Object</code> element exists.    */   public ObjectContainer getObjectItem(int i) {      Element objElem = XMLUtils.selectDsNode(this._constructionElement.getFirstChild(),            Constants._TAG_OBJECT,i);      try {         return new ObjectContainer(objElem, this._baseURI);      } catch (XMLSecurityException ex) {         return null;      }   }   /**    * Returns the number of all <code>ds:Object</code> elements.    *    * @return the number of all <code>ds:Object</code> elements.    */   public int getObjectLength() {      return this.length(Constants.SignatureSpecNS, Constants._TAG_OBJECT);   }   /**    * Digests all References in the SignedInfo, calculates the signature value and    * sets it in the SignatureValue Element.    *    * @param signingKey the {@link java.security.PrivateKey} or {@link javax.crypto.SecretKey} that is used to sign.    * @throws XMLSignatureException    */   public void sign(Key signingKey) throws XMLSignatureException {      if (signingKey instanceof PublicKey) {         throw new IllegalArgumentException(I18n            .translate("algorithms.operationOnlyVerification"));      }      try {         if (this._state == MODE_SIGN) {            // XMLUtils.indentSignature(this._constructionElement, "   ", 0);            // get the SignatureMethodElement            Element signatureMethodElement =               this._signedInfo.getSignatureMethodElement();            //Create a SignatureAlgorithm object            SignatureAlgorithm sa =               new SignatureAlgorithm(signatureMethodElement,                                      this.getBaseURI());            // initialize SignatureAlgorithm for signing            sa.initSign(signingKey);            SignedInfo si = this.getSignedInfo();            // generate digest values for all References in this SignedInfo            si.generateDigestValues();            OutputStream so=new UnsyncBufferedOutputStream(new SignerOutputStream(sa));            try {                so.close();            } catch (IOException e) {                //Imposible            }            // get the canonicalized bytes from SignedInfo            si.signInOctectStream(so);            byte jcebytes[] = sa.sign();            // set them on the SignateValue element            this.setSignatureValueElement(jcebytes);         }      } catch (CanonicalizationException ex) {         throw new XMLSignatureException("empty", ex);      } catch (InvalidCanonicalizerException ex) {         throw new XMLSignatureException("empty", ex);      } catch (XMLSecurityException ex) {         throw new XMLSignatureException("empty", ex);      }   }   /**    * Adds a {@link ResourceResolver} to enable the retrieval of resources.    *    * @param resolver    */   public void addResourceResolver(ResourceResolver resolver) {      this.getSignedInfo().addResourceResolver(resolver);   }   /**    * Adds a {@link ResourceResolverSpi} to enable the retrieval of resources.    *    * @param resolver    */   public void addResourceResolver(ResourceResolverSpi resolver) {      this.getSignedInfo().addResourceResolver(resolver);   }   /**    * Extracts the public key from the certificate and verifies if the signature    * is valid by re-digesting all References, comparing those against the    * stored DigestValues and then checking to see if the Signatures match on    * the SignedInfo.    *    * @param cert Certificate that contains the public key part of the keypair that was used to sign.    * @return true if the signature is valid, false otherwise    * @throws XMLSignatureException    */   public boolean checkSignatureValue(X509Certificate cert)           throws XMLSignatureException {      // see if cert is null      if (cert != null) {         //check the values with the public key from the cert         return this.checkSignatureValue(cert.getPublicKey());      }             Object exArgs[] = { "Didn't get a certificate" };      throw new XMLSignatureException("empty", exArgs);         }   /**    * Verifies if the signature is valid by redigesting all References,    * comparing those against the stored DigestValues and then checking to see    * if the Signatures match on the SignedInfo.    *    * @param pk {@link java.security.PublicKey} part of the keypair or {@link javax.crypto.SecretKey} that was used to sign    * @return true if the signature is valid, false otherwise    * @throws XMLSignatureException    */   public boolean checkSignatureValue(Key pk) throws XMLSignatureException {      //COMMENT: pk suggests it can only be a public key?      //check to see if the key is not null      if (pk == null) {         Object exArgs[] = { "Didn't get a key" };         throw new XMLSignatureException("empty", exArgs);      }      // all references inside the signedinfo need to be dereferenced and      // digested again to see if the outcome matches the stored value in the      // SignedInfo.      // If _followManifestsDuringValidation is true it will do the same for      // References inside a Manifest.      try {         if (!this.getSignedInfo()                 .verify(this._followManifestsDuringValidation)) {            return false;         }         //create a SignatureAlgorithms from the SignatureMethod inside         //SignedInfo. This is used to validate the signature.         SignatureAlgorithm sa =            new SignatureAlgorithm(this.getSignedInfo()               .getSignatureMethodElement(), this.getBaseURI());         if (true) {         	if (log.isLoggable(java.util.logging.Level.FINE))                                     log.log(java.util.logging.Level.FINE, "SignatureMethodURI = " + sa.getAlgorithmURI());         	if (log.isLoggable(java.util.logging.Level.FINE))                                     log.log(java.util.logging.Level.FINE, "jceSigAlgorithm    = " + sa.getJCEAlgorithmString());         	if (log.isLoggable(java.util.logging.Level.FINE))                                     log.log(java.util.logging.Level.FINE, "jceSigProvider     = " + sa.getJCEProviderName());         	if (log.isLoggable(java.util.logging.Level.FINE))                                     log.log(java.util.logging.Level.FINE, "PublicKey = " + pk);         }         sa.initVerify(pk);         // Get the canonicalized (normalized) SignedInfo         SignerOutputStream so=new SignerOutputStream(sa);         OutputStream bos=new UnsyncBufferedOutputStream(so);         this._signedInfo.signInOctectStream(bos);         try {			bos.close();		} catch (IOException e) {			//Imposible		}                  //retrieve the byte[] from the stored signature         byte sigBytes[] = this.getSignatureValue();         //Have SignatureAlgorithm sign the input bytes and compare them to the         //bytes that were stored in the signature.         boolean verify = sa.verify(sigBytes);         return verify;      } catch (XMLSecurityException ex) {         throw new XMLSignatureException("empty", ex);      }    }   /**    * Add a Reference with full parameters to this Signature    *    * @param referenceURI URI of the resource to be signed. Can be null in which    * case the dereferencing is application specific. Can be "" in which it's    * the parent node (or parent document?). There can only be one "" in each    * signature.    * @param trans Optional list of transformations to be done before digesting    * @param digestURI Mandatory URI of the digesting algorithm to use.    * @param ReferenceId Optional id attribute for this Reference    * @param ReferenceType Optional mimetype for the URI    * @throws XMLSignatureException    */   public void addDocument(           String referenceURI, Transforms trans, String digestURI, String ReferenceId, String ReferenceType)              throws XMLSignatureException {      this._signedInfo.addDocument(this._baseURI, referenceURI, trans,                                   digestURI, ReferenceId, ReferenceType);   }   /**    * This method is a proxy method for the {@link Manifest#addDocument} method.    *    * @param referenceURI URI according to the XML Signature specification.    * @param trans List of transformations to be applied.    * @param digestURI URI of the digest algorithm to be used.    * @see Manifest#addDocument    * @throws XMLSignatureException    */   public void addDocument(           String referenceURI, Transforms trans, String digestURI)              throws XMLSignatureException {      this._signedInfo.addDocument(this._baseURI, referenceURI, trans,                                   digestURI, null, null);   }   /**    * Adds a Reference with just the URI and the transforms. This used the    * SHA1 algorithm as a default digest algorithm.    *    * @param referenceURI URI according to the XML Signature specification.    * @param trans List of transformations to be applied.    * @throws XMLSignatureException    */   public void addDocument(String referenceURI, Transforms trans)           throws XMLSignatureException {      this._signedInfo.addDocument(this._baseURI, referenceURI, trans,                                   Constants.ALGO_ID_DIGEST_SHA1, null, null);   }   /**    * Add a Reference with just this URI. It uses SHA1 by default as the digest    * algorithm    *    * @param referenceURI URI according to the XML Signature specification.    * @throws XMLSignatureException    */   public void addDocument(String referenceURI) throws XMLSignatureException {      this._signedInfo.addDocument(this._baseURI, referenceURI, null,                                   Constants.ALGO_ID_DIGEST_SHA1, null, null);   }   /**    * Add an X509 Certificate to the KeyInfo. This will include the whole cert    * inside X509Data/X509Certificate tags.    *    * @param cert Certificate to be included. This should be the certificate of the key that was used to sign.    * @throws XMLSecurityException    */   public void addKeyInfo(X509Certificate cert) throws XMLSecurityException {      X509Data x509data = new X509Data(this._doc);      x509data.addCertificate(cert);      this.getKeyInfo().add(x509data);   }   /**    * Add this public key to the KeyInfo. This will include the complete key in    * the KeyInfo structure.    *    * @param pk    */   public void addKeyInfo(PublicKey pk) {      this.getKeyInfo().add(pk);   }   /**    * Proxy method for {@link SignedInfo#createSecretKey(byte[])}. If you want to    * create a MAC, this method helps you to obtain the {@link javax.crypto.SecretKey}    * from octets.    *    * @param secretKeyBytes    * @return the secret key created.    * @see SignedInfo#createSecretKey(byte[])    */   public SecretKey createSecretKey(byte[] secretKeyBytes)   {      return this.getSignedInfo().createSecretKey(secretKeyBytes);   }   /**    * Signal wether Manifest should be automatically validated.    * 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.    *    * @param followManifests    * @see <a href="http://www.w3.org/TR/xmldsig-core/#sec-CoreValidation">Core validation section in the XML Signature Rec.</a>    */   public void setFollowNestedManifests(boolean followManifests) {      this._followManifestsDuringValidation = followManifests;   }   /**    * Get the local name of this element    *    * @return Constant._TAG_SIGNATURE    */   public String getBaseLocalName() {      return Constants._TAG_SIGNATURE;   }}

⌨️ 快捷键说明

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