数字签名代码仅在AIX上失败

时间:2015-02-23 09:00:19

标签: java dom digital-signature

我有以下代码对输入XML文件进行数字签名。出于某种原因,它适用于Windows和Solaris,但无论XML内容是什么,它总是在AIX上失败。

public class Test {

    public static void main(String[] args) throws Exception {
            KeyStore keyStore = KeyStore.getInstance("JKS");
            FileInputStream fileInputStream = new FileInputStream(args[0]);
            keyStore.load(fileInputStream, "password".toCharArray());
            String alias = keyStore.aliases().nextElement();
            PrivateKey privateKey = (PrivateKey) keyStore.getKey(alias, "password".toCharArray());
            byte[] signed = createDigitalSignature(args[1], null, privateKey);
            FileOutputStream fileOutputStream = new FileOutputStream(args[2]);
            fileOutputStream.write(signed);
            fileOutputStream.close();
    }

    public static byte[] createDigitalSignature(String inputFileName, String certificateFileName, PrivateKey privateKey) throws Exception {
            XMLSignatureFactory signatureFactory = XMLSignatureFactory.getInstance("DOM");
            Transform transform = signatureFactory.newTransform("http://www.w3.org/2001/10/xml-exc-c14n#", (TransformParameterSpec) null);
            Reference reference = signatureFactory.newReference("#XXX", signatureFactory.newDigestMethod("http://www.w3.org/2001/04/xmlenc#sha256", null), Collections.singletonList(transform), null, null);
            DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
            documentBuilderFactory.setNamespaceAware(true);
            documentBuilderFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
            Document document = documentBuilderFactory.newDocumentBuilder().parse(new FileInputStream(inputFileName));
            XMLStructure structure = new DOMStructure(document.getDocumentElement());
            XMLObject object = signatureFactory.newXMLObject(Collections.singletonList(structure), "XXX", null, null);
            SignatureMethod signatureMethod = signatureFactory.newSignatureMethod("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256", null);
            CanonicalizationMethod canonicalizationMethod = signatureFactory.newCanonicalizationMethod("http://www.w3.org/2001/10/xml-exc-c14n#", (C14NMethodParameterSpec)null);
            SignedInfo signedInfo = signatureFactory.newSignedInfo(canonicalizationMethod, signatureMethod, Collections.singletonList(reference));
            KeyInfo keyInfo = null;
            if (certificateFileName != null) {
                FileInputStream fileInputStream = new FileInputStream(certificateFileName);
                CertificateFactory factory = CertificateFactory.getInstance("X.509");
                X509Certificate certificate = (X509Certificate) factory.generateCertificate(fileInputStream);
                ArrayList<Object> x509Content = new ArrayList<Object>();
                x509Content.add(certificate.getSubjectX500Principal().getName());
                x509Content.add(certificate);
                KeyInfoFactory keyInfoFactory = signatureFactory.getKeyInfoFactory();
                X509Data xd = keyInfoFactory.newX509Data(x509Content);
                keyInfo = keyInfoFactory.newKeyInfo(Collections.singletonList(xd));
            }
            XMLSignature signature = signatureFactory.newXMLSignature(signedInfo, keyInfo, Collections.singletonList(object), null, null);
            DOMSignContext signContext = new DOMSignContext(privateKey, document);
            signature.sign(signContext);
            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            Transformer transformer = transformerFactory.newTransformer();
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            transformer.transform(new DOMSource(document), new StreamResult(byteArrayOutputStream));
            return byteArrayOutputStream.toByteArray();
    }
}

我得到的例外是:

Exception in thread "main" org.w3c.dom.DOMException: HIERARCHY_REQUEST_ERR: An attempt was made to insert a node where it is not permitted. 
        at org.apache.xerces.dom.CoreDocumentImpl.insertBefore(Unknown Source)
        at com.ibm.xml.crypto.dsig.dom.XMLSignatureImpl.sign(XMLSignatureImpl.java:158)

它被抛出线:signature.sign(signContext);

可能是什么问题?我有一个像

这样简单的XML文件
<?xml version="1.0" encoding="UTF-8" ?> 
<a>
</a>

但它仍然失败,仅在AIX上!

0 个答案:

没有答案