Domino服务器上的XML签名不同

时间:2013-08-05 12:02:21

标签: java xml windows lotus-domino xml-signature

描述

我们正在尝试与服务提供商建立通信,要求我们签署我们发送的XML。这是在使用Java 1.6的Lotus Domino平台上完成的。 问题是,使用Domino JRE运行代码时生成的签名与使用常规JRE在Eclipse中运行代码时的签名不同。在Domino中运行时,它会在接收端触发验证错误。因此,在Eclipse中使用相同的代码并仅针对IBM JRE会导致此错误。 这很明显,Domino JRE中有一些东西会导致这个问题出错,我们只是不知道是什么或如何找到它的底部。 任何想法是什么设置可能是造成这种差异的原因?

为了澄清,请注意我们对所有测试使用相同的内容,并且在Eclipse中运行两次会产生完全相同的结果。

错误消息

返回的错误只是表示签名无效: 2013-08-05 16:38:18代理管理器:代理错误:ESignClientException:ESigningFacade.getOrder失败。原因:(RMS返回错误响应.TransId [-1971835324952692066] RMS ErrorCode [RMS1002] ErrorText [SignatureVerification failed.Signature无效。]

代码

我们正在使用服务提供商API,但这里是我们正在运行的代码的简短示例:

public void test() {
    try {
        String xmlrequest = "SOME XML"
        String keyStorePath = "keystore.p12";
        char[] pwdChars = "********".toCharArray();
        PrivateKey privateKey = null;
        String providerName = System.getProperty("jsr105Provider", "org.jcp.xml.dsig.internal.dom.XMLDSigRI");
        XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM", (Provider) Class.forName(providerName).newInstance());
        KeyInfoFactory kif = fac.getKeyInfoFactory();

        KeyStore store = KeyStore.getInstance("PKCS12");
        store.load(new FileInputStream(keyStorePath), pwdChars);

        Enumeration ksAliases = store.aliases();
        String keyAlias = null;
        while (ksAliases.hasMoreElements()) {
            String currAlias = (String) ksAliases.nextElement();
            if (store.isKeyEntry(currAlias)) {
                keyAlias = currAlias;
                privateKey = ((PrivateKey) store.getKey(currAlias, pwdChars));
                break;
            }
        }

        Certificate certificate = store.getCertificate(keyAlias);
        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        X509Certificate cert = (X509Certificate) cf.generateCertificate(new   ByteArrayInputStream(certificate.getEncoded()));
        X509Data x5 = kif.newX509Data(Collections.nCopies(1, cert));
        KeyInfo ki = kif.newKeyInfo(Collections.nCopies(1, x5));
        Reference ref = fac.newReference("#object", fac.newDigestMethod("http://www.w3.org/2000/09/xmldsig#sha1", null));

        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        dbf.setNamespaceAware(true);
        dbf.setValidating(false);
        dbf.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage", "http://www.w3.org/2001/XMLSchema");
        DocumentBuilder db = dbf.newDocumentBuilder();
        Document doc = db.parse(new InputSource(new StringReader(xmlrequest)));
        XMLStructure content = new DOMStructure(doc.getFirstChild());

        XMLObject obj = fac.newXMLObject(Collections.nCopies(1, content), "object", null, null);
        SignedInfo si =    fac.newSignedInfo(fac.newCanonicalizationMethod("http://www.w3.org/2001/10/xml-exc-c14n#", (C14NMethodParameterSpec) null),                fac.newSignatureMethod("http://www.w3.org/2000/09/xmldsig#rsa-sha1", null),       Collections.nCopies(1, ref));
        XMLSignature signature = fac.newXMLSignature(si, ki, Collections.nCopies(1, obj), null, null);
        DOMSignContext dsc = new DOMSignContext(privateKey, doc);
        signature.sign(dsc);

        ByteArrayOutputStream os = new ByteArrayOutputStream();
        TransformerFactory tf = TransformerFactory.newInstance();
        Transformer trans = tf.newTransformer();
        trans.transform(new DOMSource(doc), new StreamResult(os));
        os.flush();
        String res = new String(os.toByteArray(), "UTF-8");
        os.close();

    } catch (Exception e) {
        e.printStackTrace();
    }
}

1 个答案:

答案 0 :(得分:0)

好的,经过大量的试验和错误,我自己设法解决了这个问题。由于提供程序“org.jcp.xml.dsig.internal.dom.XMLDSigRI”未包含在IBM JRE中,因此它也未添加到java.security文件(jvm / lib / security / java.security)中。 所以我在java.security文件中为新提供程序添加了一行,然后就可以了。或者我想。它只适用于我使用IBM JRE的Eclipse测试项目。当我在服务器上尝试相同的修复时,它根本没有任何影响。当我像以前一样将提供程序添加到java.security文件时,提供程序列表没有更改。 因此,经过一些测试,我发现提供程序在我将提供程序JAR(xmlsec-1.4.2.jar)添加到文件夹“jvm / lib / ext /”时已注册。这就是我的工作方式。