XML签名验证

- 签名xml标准格式如下:
<dj xmlns="http://cmsland.com/yjj_qyjk_scrk.xsd">
  <tm bwm="86903168000649" bzgg="" scph="20120501" scrq="2012-05-01" yxqz="2015-05-01" sl="2000" />
  <tm bwm="86903168000649" bzgg="" scph="20120502" scrq="2012-05-02" yxqz="2015-05-02" sl="3000" />
- <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
- <SignedInfo>
  <CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
  <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-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>gIt77b5E2Sg8aCyW4ePMuReg3DY=</DigestValue>
  </Reference>
  </SignedInfo>
  <SignatureValue>YOv1da4q7JhbiEwzpoPbaBy3GYMgyWNaiJwX+FuoC0lo83yYX4VqfXfjNQ0YnNX4cfbdReeX9V7SJ8lqsddfn47njHm0BdX1+Nx71EZAWdwKAiJimPP8mvv4hVYSTbM3pIUEHlWRtPgfWiPSHPh6ml39BzDl15P0Fjzla1xi+dY=</SignatureValue>
- <KeyInfo>
- <X509Data>
- <X509IssuerSerial>
  <X509IssuerName>System.Security.Cryptography.X509Certificates.X500DistinguishedName</X509IssuerName>
  <X509SerialNumber>53721960771501034418789216508892913400</X509SerialNumber>
  </X509IssuerSerial>
  <X509Certificate>MIID9zCCAt+gAwIBAgIQKGp5KavX8ujDBgo/bvee+DANBgkqhkiG9w0BAQUFADB3MQswCQYDVQQGEwJDTjEkMCIGA1UEChMbTkVUQ0EgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MR0wGwYDVQQLExRJbmRpdmlkdWFsIENsYXNzQSBDQTEjMCEGA1UEAxMaTkVUQ0EgSW5kaXZpZHVhbCBDbGFzc0EgQ0EwHhcNMTIwNDE4MTYwMDAwWhcNMTMwNDE5MTU1OTU5WjBkMQswCQYDVQQGEwJDTjESMBAGA1UECBMJR3Vhbmdkb25nMSUwIwYDVQQDHhxOKk66bUuL1QAyADAAMQAxADAANAAyADIAMQA2MRowGAYJKoZIhvcNAQkBFgt6c0BjbmNhLm5ldDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA1ydRUYSdoofmMeyrY2i/pwzjUaGYLWQyS1W2Z30+V/uSiRRR/QwpeiSOuJcnPAkjuvgiTMz4+eWzWn9rHS56I5RPJaf27juRQoA3Ej+xSahRZSWs2hv0rBXRikAStuwo4uk3hI+Tct98dN9EWBJLPJdYj7ZNMnY8wg+wG91C88kCAwEAAaOCARQwggEQMB8GA1UdIwQYMBaAFLFHZEQZX2XMQLsGS+l5BOAe7LVOMB0GA1UdDgQWBBS6/ou1RSKMmjcY8p2cNjRL/3aaxDBXBgNVHSAEUDBOMEwGCisGAQQBgZJIAQowPjA8BggrBgEFBQcCARYwaHR0cDovL3d3dy5jbmNhLm5ldC9jcy9rbm93bGVkZ2Uvd2hpdGVwYXBlci9jcHMvMBYGA1UdEQQPMA2BC3pzQGNuY2EubmV0MAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgbAMD8GA1UdHwQ4MDYwNKAyoDCGLmh0dHA6Ly9jbGFzc2FjYTEuY25jYS5uZXQvY3JsL0luZGl2aWR1YWxDQS5jcmwwDQYJKoZIhvcNAQEFBQADggEBAAYW3lOrOLP27xPsec3TvYYTjSdl8sTLaxy3UtFFt3Bgx0CgjiGyoDtacr+2xUk57VLK7XtmtZx/aN+GGjJUpiKni9em1KoxyXQDIrEMjhzS5VEkwlO0xrJsAASICtM9smGWe5yCVm3RGD5U7F9xi8l1BgIsaRWUVzQ2ObzXjA8AMviTmcqMEZGDmNVlyxRyg5yN9GqOWQBthDWZsdqU8wEoI4e+gHyMwCIs4baDtkrb1fyDrcxsuDKnSU0zcfgwpOzFLTht+Ibu4J00s95ciDjXCQ5h2Z2aW6r3cMf/ap5g9FvCm/A2DEAS2Hqws1fvALNJgPehnDdfhOiFz/2MiXY=</X509Certificate>
  </X509Data>
  </KeyInfo>
  </Signature>
  </dj>
 
 
通过 java验证该签名的方式(借鉴ibm 稍有修改)如下:
 

import java.io.FileInputStream;
import java.security.PublicKey;
import java.util.List;

import javax.xml.crypto.dom.DOMStructure;
import javax.xml.crypto.dsig.Reference;
import javax.xml.crypto.dsig.XMLSignature;
import javax.xml.crypto.dsig.XMLSignatureFactory;
import javax.xml.crypto.dsig.dom.DOMValidateContext;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import sun.security.x509.X509CertImpl;

public class Test {

 /**
  * @param args
  * @throws Exception
  */
 public static void main(String[] args) throws Exception {
  // TODO Auto-generated method stub
  validate("生产入库记录.xml");
 }

 private static void validate(String signedFile) throws Exception {
  // Parse the signed XML document to unmarshal <Signature> object.
  DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
  dbf.setNamespaceAware(true);
  Document doc = dbf.newDocumentBuilder().parse(
    new FileInputStream(signedFile));

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

  XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM");
  XMLSignature signature = fac.unmarshalXMLSignature(new DOMStructure(
    signatureNode));
  javax.xml.crypto.dsig.keyinfo.X509Data data=(javax.xml.crypto.dsig.keyinfo.X509Data)signature.getKeyInfo().getContent().get(
    0);
  // Get the public key for signature validation
//  KeyValue keyValue = (KeyValue) signature.getKeyInfo().getContent().get(
//    0);
  List l=data.getContent();
  javax.xml.crypto.dsig.keyinfo.X509IssuerSerial searial=(javax.xml.crypto.dsig.keyinfo.X509IssuerSerial)l.get(0);
  X509CertImpl cert=(X509CertImpl)l.get(1);
  PublicKey pubKey=cert.getPublicKey() ;//= data.getPublicKey();
 
  // Create ValidateContext
  DOMValidateContext valCtx = new DOMValidateContext(pubKey,
    signatureNode);

  // Validate the XMLSignature
  boolean coreValidity = signature.validate(valCtx);

  // Check core validation status
  if (coreValidity == false) {
   System.err.println("Core validation failed");
   // Check the signature validation status
   boolean sv = signature.getSignatureValue().validate(valCtx);
   System.out.println("Signature validation status: " + sv);
   // check the validation status of each Reference
   List refs = signature.getSignedInfo().getReferences();
   for (int i = 0; i < refs.size(); i++) {
    Reference ref = (Reference) refs.get(i);
    boolean refValid = ref.validate(valCtx);
    System.out.println("Reference[" + i + "] validity status: "
      + refValid);
   }
  } else {
   System.out.println("Signature passed core validation");
  }
 }
}

原文地址:https://www.cnblogs.com/liaomin416100569/p/9331365.html