XmlSignUtil.java 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. /**
  2. * Alipay.com Inc.
  3. * Copyright (c) 2004-2016 All Rights Reserved.
  4. */
  5. package com.huilian.api.open.huilianjavademo;
  6. import org.apache.xml.security.signature.XMLSignature;
  7. import org.apache.xml.security.transforms.Transforms;
  8. import org.apache.xml.security.utils.Constants;
  9. import org.apache.xml.security.utils.XMLUtils;
  10. import org.w3c.dom.Document;
  11. import org.w3c.dom.Node;
  12. import org.w3c.dom.NodeList;
  13. import org.xml.sax.InputSource;
  14. import org.xml.sax.SAXException;
  15. import javax.xml.parsers.DocumentBuilder;
  16. import javax.xml.parsers.DocumentBuilderFactory;
  17. import javax.xml.parsers.ParserConfigurationException;
  18. import java.io.*;
  19. import java.security.PrivateKey;
  20. import java.security.PublicKey;
  21. /**
  22. * 进行签名验签的测试
  23. *
  24. * @author jin.xie
  25. * @version $Id: XmlSignTest.java, v 0.1 2016年2月1日 上午10:51:39 jin.xie Exp $
  26. */
  27. public class XmlSignUtil {
  28. private static final String CHARSET = "UTF-8";
  29. private static final String SIGN_ALGORITHM = "SHA256withRSA";
  30. private static final String XML_ALGORITHM = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";
  31. private static final String REQUEST_TAG_NAME = "request";
  32. private static final String RESPONSE_TAG_NAME = "response";
  33. private static final String SIGNATURE_TAG_NAME = "Signature";
  34. /**
  35. * 签名- XML
  36. *
  37. * @throws Exception
  38. */
  39. public static String sign(String xmlContent,String RsaPrivateKey) throws Exception {
  40. Document doc = parseDocumentByString(xmlContent);
  41. PrivateKey privateKey = SignatureUtils.getPrivateKey(RsaPrivateKey);
  42. String result = SignatureUtils.signXmlElement(privateKey, doc, "request",
  43. XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA256, 2);
  44. return result;
  45. }
  46. public static String signRes(String xmlContent,String RsaPrivateKey) throws Exception {
  47. Document doc = parseDocumentByString(xmlContent);
  48. PrivateKey privateKey = SignatureUtils.getPrivateKey(RsaPrivateKey);
  49. String result = SignatureUtils.signXmlElement(privateKey, doc, "response",
  50. XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA256, 2);
  51. return result;
  52. }
  53. /**
  54. * 私钥签名应答报文
  55. *
  56. * @param responseMessage
  57. * @param privateKey
  58. * @return
  59. * @throws Exception
  60. */
  61. public static String signResponseMessage(String responseMessage, PrivateKey privateKey)
  62. throws Exception {
  63. return signXmlMessage(responseMessage, RESPONSE_TAG_NAME, privateKey);
  64. }
  65. /**
  66. * 私钥签名
  67. *
  68. * @param xmlMessageSource 待签名的XML
  69. * @param elementTagName
  70. * @param privateKey
  71. * @return
  72. * @throws Exception
  73. */
  74. public static String signXmlMessage(String xmlMessageSource, String elementTagName,
  75. PrivateKey privateKey) throws Exception {
  76. //org.apache.xml.security.Init.init();
  77. Document xmlDocument = getDocument(xmlMessageSource);
  78. XMLSignature xmlSignature = new XMLSignature(xmlDocument, xmlDocument.getDocumentURI(),
  79. XML_ALGORITHM);
  80. NodeList nodeList = xmlDocument.getElementsByTagName(elementTagName);
  81. if (nodeList == null || nodeList.getLength() != 1) {
  82. throw new Exception("Document element with tag name " + elementTagName + " not fount");
  83. }
  84. Node elementNode = nodeList.item(0);
  85. elementNode.getParentNode().appendChild(xmlSignature.getElement());
  86. Transforms transforms = new Transforms(xmlDocument);
  87. transforms.addTransform(Transforms.TRANSFORM_ENVELOPED_SIGNATURE);
  88. xmlSignature.addDocument("", transforms, Constants.ALGO_ID_DIGEST_SHA1);
  89. xmlSignature.sign(privateKey);
  90. ByteArrayOutputStream os = new ByteArrayOutputStream();
  91. XMLUtils.outputDOM(xmlDocument, os);
  92. return os.toString(CHARSET);
  93. }
  94. /**
  95. * 解析XML字符串
  96. *
  97. * @param xmlMessageSource
  98. * @return
  99. * @throws ParserConfigurationException
  100. * @throws SAXException
  101. * @throws IOException
  102. * @throws UnsupportedEncodingException
  103. */
  104. private static Document getDocument(String xmlMessageSource)
  105. throws ParserConfigurationException,
  106. SAXException, IOException,
  107. UnsupportedEncodingException {
  108. DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
  109. factory.setNamespaceAware(true);
  110. DocumentBuilder builder = factory.newDocumentBuilder();
  111. Document xmlDocument = builder.parse(new InputSource(new ByteArrayInputStream(
  112. xmlMessageSource.getBytes(CHARSET))));
  113. return xmlDocument;
  114. }
  115. /**
  116. * 验签 - XML
  117. *
  118. * @throws Exception
  119. */
  120. public static boolean verify(String xmlContent,String RsaPublicKey) throws Exception {
  121. Document doc = parseDocumentByString(xmlContent);
  122. PublicKey publicKey = SignatureUtils.getPublicKey(RsaPublicKey);
  123. return SignatureUtils.verifyXmlElement(publicKey, doc);
  124. }
  125. /**
  126. * 解析XML
  127. *
  128. * @param xmlContent
  129. * @return
  130. * @throws SAXException
  131. * @throws IOException
  132. * @throws ParserConfigurationException
  133. */
  134. private static Document parseDocumentByString(String xmlContent) throws Exception {
  135. DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
  136. factory.setNamespaceAware(true);// 否则无法识别namespace
  137. return factory.newDocumentBuilder().parse(new InputSource(new StringReader(xmlContent)));
  138. }
  139. }