描述
我们正在尝试与要求我们签署我们发送的 XML 的服务提供商建立通信。这是在使用 Java 1.6 的 Lotus Domino 平台上完成的。问题在于,使用 Domino JRE 运行代码时生成的签名与使用常规 JRE 在例如 Eclipse 中运行代码时生成的签名不同。在 Domino 中运行时,它会在接收端触发验证错误。因此,在 Eclipse 中使用相同的代码并仅针对 IBM JRE 会导致此错误。这很清楚地表明,Domino JRE 中有一些东西导致了这个问题,我们只是不知道是什么或如何找到它的底部。任何想法什么设置可能是造成这种差异的原因?
为澄清起见,请注意我们对所有测试使用相同的内容,并且在 Eclipse 中运行 i 两次会产生完全相同的结果。
错误信息
返回的错误只是说签名无效:2013-08-05 16:38:18 Agent Manager: Agent error: ESignClientException: ESigningFacade.getOrder failed。原因:(RMS 返回错误响应。TransId [-1971835324952692066] RMS ErrorCode [RMS1002] ErrorText [SignatureVerification failed. The Signature is not valid.])
代码
我们正在使用服务提供者 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();
}
}