Digital signing code fails only on AIX

China☆狼群 提交于 2019-12-11 13:53:20

问题


I have the following codes which digitally signs an input XML file. For some reason, it works on Windows and Solaris, but it always fail on AIX no matter what the XML content is.

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();
    }
}

The exception that I'm getting is:

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)

It's thrown at the line: signature.sign(signContext);

What could be the problem? I have an XML file as simple as

<?xml version="1.0" encoding="UTF-8" ?> 
<a>
</a>

but it still fails, only on AIX!

来源:https://stackoverflow.com/questions/28670003/digital-signing-code-fails-only-on-aix

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!