我们正在尝试与服务提供商建立通信,要求我们签署我们发送的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();
}
}
答案 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 /”时已注册。这就是我的工作方式。