Java::XML电子签名代码

例子

test.xml

<license>
    <test>hello world</test>
</license>

test_sign.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<license>
	<test>hello world</test>
	<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>YtX4fzWIPzHuoJXrIbSCCJwizPs=</DigestValue>
			</Reference>
		</SignedInfo>
		<SignatureValue>B1fRTKI1JJNqVr3vL+rrBVuTzDP/6+V9dkRp5tCoDzwhipcHVHkr2fRYDDu3tIGg7blBj+GkGTW7
ZPKjLng7I+y5LhNMZM6X6foD1bX9wp8YyI5X1uBbrdV804DRvbfZ2HuT3/BnT1IlTLsgVumxw4vf
fS1goAqgr6uoOs7yr/A=</SignatureValue>
		<KeyInfo>
			<X509Data>
				<X509Certificate>(这里显示证书ASN.1信息)
				</X509Certificate>
				<X509SubjectName>CN=test,OU=test,OU=112222222,L=SHENZHEN,ST=GUANGDONG,C=CN</X509SubjectName>
			</X509Data>
		</KeyInfo>
	</Signature>
</license>

这里写图片描述

代码

签名

 try {
            XMLSignatureFactory xmlSignatureFactory = XMLSignatureFactory.getInstance("DOM");

            Transform envelopedTransform = xmlSignatureFactory.newTransform(Transform.ENVELOPED , (XMLStructure) null);
            DigestMethod sha1DigestMethod = xmlSignatureFactory.newDigestMethod(DigestMethod.SHA1 , null);

            //创建reference元素
            Reference reference = xmlSignatureFactory.newReference("" ,
                    sha1DigestMethod ,
                    Collections.singletonList(envelopedTransform),
                    null , null);

            SignatureMethod rsaSignatureMethod = xmlSignatureFactory.newSignatureMethod(SignatureMethod.RSA_SHA1 , null);
            CanonicalizationMethod canonicalizationMethod = xmlSignatureFactory.newCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE ,
                    (XMLStructure) null);
            //创建SignedInfo元素
            SignedInfo signedInfo = xmlSignatureFactory.newSignedInfo(
                    canonicalizationMethod ,
                    rsaSignatureMethod,
                    Collections.singletonList(reference));

            //创建密钥对
            KeyStore keyStore = KeyStore.getInstance("PKCS12");



            File file = new File(pfxFile);
            FileInputStream fis = new FileInputStream(file);
            keyStore.load(fis, password);
            fis.close();

            //获取别名
            Enumeration enumas = keyStore.aliases();
            String alias = null;
            while (enumas.hasMoreElements()) {
                alias = (String) enumas.nextElement();
            }

            //准备密钥对
            Key key = keyStore.getKey(alias, password);
            KeyPair keyPair = null;
            if (key instanceof PrivateKey) {
                Certificate cert = keyStore.getCertificate(alias);
                PublicKey publicKey = cert.getPublicKey();
                keyPair = new KeyPair(publicKey, (PrivateKey) key);
            }

            X509Certificate x509 = (X509Certificate) keyStore.getCertificate(alias);

            KeyInfoFactory keyInfoFactory = xmlSignatureFactory.getKeyInfoFactory();
            List x509Content = new ArrayList();
            x509Content.add(x509);
            x509Content.add(x509.getSubjectX500Principal().getName());
            X509Data x509Data = keyInfoFactory.newX509Data(x509Content);
            KeyInfo keyInfo = keyInfoFactory.newKeyInfo(Collections.singletonList(x509Data));

            DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
            documentBuilderFactory.setNamespaceAware(true);
            Document document = documentBuilderFactory.newDocumentBuilder().
                    parse(new FileInputStream(srcFile));
            DOMSignContext domSignContext = new DOMSignContext(keyPair.getPrivate() , document.getDocumentElement());
            
            //创建Signature元素
            XMLSignature xmlSignature = xmlSignatureFactory.newXMLSignature(signedInfo , keyInfo);
            xmlSignature.sign(domSignContext);


            //输出处理后的文件
            OutputStream outputStream = new FileOutputStream(dstFile);
            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            Transformer transformer = transformerFactory.newTransformer();
            transformer.transform(new DOMSource(document) , new StreamResult(outputStream));


        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidAlgorithmParameterException e) {
            e.printStackTrace();
        } catch (KeyStoreException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (UnrecoverableKeyException e) {
            e.printStackTrace();
        } catch (CertificateException e) {
            e.printStackTrace();
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (XMLSignatureException e) {
            e.printStackTrace();
        } catch (MarshalException e) {
            e.printStackTrace();
        } catch (TransformerConfigurationException e) {
            e.printStackTrace();
        } catch (TransformerException e) {
            e.printStackTrace();
        }

验签

 try {
            DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
            documentBuilderFactory.setNamespaceAware(true);

            Document document = documentBuilderFactory.newDocumentBuilder().
                    parse(new FileInputStream(dstFile));
            NodeList nodeList = document.getElementsByTagNameNS(XMLSignature.XMLNS , "Signature");

            if(nodeList.getLength() == 0){
                throw new Exception("Cannot find Signature element");
            }

            DOMValidateContext validateContext = new DOMValidateContext(new X509KeySelector() , nodeList.item(0));

            XMLSignatureFactory xmlSignatureFactory = XMLSignatureFactory.getInstance("DOM");
            XMLSignature xmlSignature = xmlSignatureFactory.unmarshalXMLSignature(validateContext);

            boolean result = xmlSignature.validate(validateContext);
            
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
public class X509KeySelector extends KeySelector {
    @Override
    public KeySelectorResult select(KeyInfo keyInfo, Purpose purpose, AlgorithmMethod method, XMLCryptoContext context)
            throws KeySelectorException {

        Iterator keyInfos = keyInfo.getContent().iterator();
        while (keyInfos.hasNext()) {
            XMLStructure xmlStructure = (XMLStructure) keyInfos.next();
            if (!(xmlStructure instanceof X509Data)) {
                continue;
            }

            X509Data x509Data = (X509Data) xmlStructure;

            Iterator x509s = x509Data.getContent().iterator();
            while (x509s.hasNext()) {
                Object object = x509s.next();
                if (!(object instanceof X509Certificate)) {
                    continue;
                }

                final PublicKey publicKey = ((X509Certificate) object).getPublicKey();

                if (algEquals(method.getAlgorithm() , publicKey.getAlgorithm())) {
                    return new KeySelectorResult() {
                        @Override
                        public Key getKey() {
                            return publicKey;
                        }
                    };
                }
            }
        }
        throw new KeySelectorException("No key found");
    }


    static boolean algEquals(String algURI , String algName){
        if (algName.equalsIgnoreCase("DSA") && algURI.equalsIgnoreCase(SignatureMethod.DSA_SHA1)
                || algName.equalsIgnoreCase("RSA") && algURI.equalsIgnoreCase(SignatureMethod.RSA_SHA1)) {
            return true;
        }
        return false;
    }
}

参考

Programming With the Java XML Digital Signature API

Java SE 6中 XML 数字签名的标准 Java 接口

XML Signature WG

An Introduction to XML Digital Signatures

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值