xml签名验签模拟程序

package com.kame.micropay.netbank.service.adapter.b2c;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Collections;
import java.util.Enumeration;

import javax.xml.crypto.dom.DOMStructure;
import javax.xml.crypto.dsig.XMLSignatureFactory;
import javax.xml.crypto.dsig.dom.DOMSignContext;
import javax.xml.crypto.dsig.dom.DOMValidateContext;
import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec;
import javax.xml.crypto.dsig.spec.TransformParameterSpec;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

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

/**
* xml签名验签模拟程序
*/

public class SignForXML {

public static void main(String[] args) throws Exception {
String pubKeyFile = "F:/home/weblogic/profiles/kame-bank/cert/pingan/kmpay.cer";
String priKeyFile = "F:/home/weblogic/profiles/kame-bank/cert/pingan/kmpay.pfx";
String priKeyPsw = "111111";
String signNode = "PAFPReq";
//加签
String forSignatureStr = "";
forSignatureStr = forSignatureStr+"<Fastpay>";
forSignatureStr = forSignatureStr+" <Message id=\"1234567890123\">";
forSignatureStr = forSignatureStr+" <PAFPReq id=\"PAFPReq\">";
forSignatureStr = forSignatureStr+" <date>20100330 11:51:39</date>";
forSignatureStr = forSignatureStr+"      <tranCode>"+"1001200201"+"</tranCode>";
forSignatureStr = forSignatureStr+"      <instId>1217</instId>";
forSignatureStr = forSignatureStr+"      <tradeCode>1245894125</tradeCode>";
forSignatureStr = forSignatureStr+"      <name>测试</name>";
forSignatureStr = forSignatureStr+"      <encryptData>WEGTFWEGDSAGHWERYUHWWEQEWGH</encryptData>";
forSignatureStr = forSignatureStr+" </PAFPReq>";
forSignatureStr = forSignatureStr+" </Message>";
forSignatureStr = forSignatureStr+"</Fastpay>";
String signResult = signXML(priKeyFile,priKeyPsw,priKeyPsw,"",forSignatureStr,signNode);

//验签
boolean verifySignature = verifySignature("",signResult,pubKeyFile);
if(verifySignature){
System.out.println("验证签名成功");
}else{
System.out.println("验证签名失败");
}
}

public static String signXML(String priKeyName,String keyStorePsw,String priKeyPsw,
String partnerCode ,String xmlStr,String tagName)
{
System.out.println("priKeyName:" + priKeyName);

FileInputStream priKeyStream = null;
try {
priKeyStream = new FileInputStream(priKeyName);
} catch (FileNotFoundException e) {
System.out.println("文件不存在:" + priKeyName + e);
}

PrivateKey priKey =  getPrivateKey(priKeyStream,keyStorePsw,priKeyPsw);

System.out.println("签名前的报文:" + xmlStr);
//给XML签名
String signedXML = signXml(xmlStr, priKey, "#"+tagName);
System.out.println("签名后的报文:" + signedXML);
return signedXML;
}

    /**
     *  校验对xml报文的签名
     * @return 校验失功返回true,否则返回false.
     */
    public static  boolean verifySignature(String partnerCode , String signedXmlStr,String pubKeyName) {

    System.out.println("待验签的报文:" + signedXmlStr);
    ByteArrayInputStream inputStream;
try {
inputStream = new ByteArrayInputStream(signedXmlStr.getBytes("UTF-8"));
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
Document doc = dbf.newDocumentBuilder().parse(inputStream);
NodeList nl =  doc.getElementsByTagNameNS("http://www.w3.org/2000/09/xmldsig#", "Signature");
if (nl.getLength() == 0) {
throw new Exception("Cannot find Signature element");
}

Node signatureNode = nl.item(0);

XMLSignatureFactory factory = XMLSignatureFactory.getInstance("DOM", new org.jcp.xml.dsig.internal.dom.XMLDSigRI());
javax.xml.crypto.dsig.XMLSignature signature = factory.unmarshalXMLSignature(new DOMStructure(signatureNode));

FileInputStream pubKeyStream = new FileInputStream(pubKeyName);
PublicKey pubKey = getPublicKey(pubKeyStream);

DOMValidateContext valCtx = new DOMValidateContext(pubKey, signatureNode);
boolean coreValidity = signature.validate(valCtx);
System.out.println("验签结果:" + coreValidity);
return coreValidity;

} catch (UnsupportedEncodingException e) {
System.out.println("验签异常: " + e);
e.printStackTrace();
}catch (Exception e){
System.out.println("验签异常: " + e);
e.printStackTrace();
}
    return false;
    }

private static String signXml(String msg_xml, PrivateKey priKey, String msgType)
{
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try
{
ByteArrayInputStream inputStream = new ByteArrayInputStream(msg_xml.getBytes("UTF-8"));
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
Document document = dbf.newDocumentBuilder().parse(inputStream);
StreamResult streamResult = new StreamResult(outputStream);
NodeList messageNodeList = document.getDocumentElement().getChildNodes();
for (int index = 0; index < messageNodeList.getLength(); index++)
{
Node messageNode = messageNodeList.item(index);
if (messageNode.getNodeType() != 1)
continue;
if (!"Message".equals(messageNode.getLocalName()))
{
break;
}
System.out.println("messageNode=" + messageNode.getNodeValue());
XMLSignatureFactory factory = XMLSignatureFactory.getInstance("DOM");
//jdk6.0适用上面的语句,jdk1.4改为下面的语句
//XMLSignatureFactory factory = XMLSignatureFactory.getInstance("DOM", new org.jcp.xml.dsig.internal.dom.XMLDSigRI());

DOMSignContext domSignContext = new DOMSignContext(priKey, messageNode);
javax.xml.crypto.dsig.Transform envelopedTransform = factory.newTransform("http://www.w3.org/2000/09/xmldsig#enveloped-signature",
(TransformParameterSpec) null);
javax.xml.crypto.dsig.DigestMethod digestMethod = factory.newDigestMethod("http://www.w3.org/2000/09/xmldsig#sha1", null);
javax.xml.crypto.dsig.Reference ref = factory.newReference(msgType, digestMethod, Collections
.singletonList(envelopedTransform), null, null);
javax.xml.crypto.dsig.CanonicalizationMethod canonicalizationMethod = factory.newCanonicalizationMethod(
"http://www.w3.org/TR/2001/REC-xml-c14n-20010315", (C14NMethodParameterSpec) null);
javax.xml.crypto.dsig.SignatureMethod signatureMethod = factory
.newSignatureMethod("http://www.w3.org/2000/09/xmldsig#rsa-sha1", null);
javax.xml.crypto.dsig.SignedInfo si = factory.newSignedInfo(canonicalizationMethod, signatureMethod, Collections.singletonList(ref));
javax.xml.crypto.dsig.XMLSignature signature = factory.newXMLSignature(si, null);
signature.sign(domSignContext);
}

TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty("omit-xml-declaration", "no");
transformer.transform(new DOMSource(document), streamResult);
String signedXML = outputStream.toString("UTF-8");
outputStream.close();
return signedXML;
} catch (Exception e)
{
System.out.println("XML数字签名出错:" + e);
}
finally
{
try
{
outputStream.close();
} catch (IOException e)
{
e.printStackTrace();
}
}
return null;
}

    /**
     *获取证书私钥
     * @return
     */
    private static PrivateKey getPrivateKey(InputStream priKeyName,String keyStorePsw,String priKeyPassword){
    PrivateKey priv=null;
try {
KeyStore ks = KeyStore.getInstance("PKCS12");
ks.load(priKeyName, keyStorePsw.toCharArray());

Enumeration en = ks.aliases();

String alias = null;
for (int i = 0; en.hasMoreElements(); i++) {
alias = en.nextElement().toString();
if (i >= 1) {
System.out.println("此文件中含有多个证书!");
}
}
priv = (PrivateKey) ks.getKey(alias,priKeyPassword.toCharArray());
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (CertificateException e) {
e.printStackTrace();
} catch (UnrecoverableKeyException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
    return priv;
    }
   
    private static PublicKey getPublicKey(InputStream pubKeyName){
    PublicKey pub=null;
try {
CertificateFactory certificatefactory = CertificateFactory.getInstance("X.509");
X509Certificate certificate = (X509Certificate)certificatefactory.generateCertificate(pubKeyName);
pub = certificate.getPublicKey();
} catch (CertificateException e) {
System.out.println("获取公钥异常:" + e);
e.printStackTrace();
}
    return pub;
    }
}

猜你喜欢

转载自tangkuo.iteye.com/blog/2284797
今日推荐