説明
送信する XML に署名する必要があるサービス プロバイダーとの通信を設定しようとしています。これは、Java 1.6 を使用する Lotus Domino プラットフォームで行われます。問題は、Domino JRE を使用してコードを実行する場合と、通常の JRE を使用して Eclipse で実行する場合とでは、生成される署名が異なることです。Domino で実行すると、受信側で検証エラーが発生します。そのため、Eclipse で同じコードを使用し、代わりに IBM JRE をターゲットにすると、このエラーが発生します。これは、Domino JRE に問題を引き起こしている何かがあることを明確にしています。この違いの原因となる設定は何ですか?
明確にするために、すべてのテストに同じ内容を使用していること、および Eclipse で i を 2 回実行するとまったく同じ結果が得られることに注意してください。
エラーメッセージ
返されるエラーは、署名が無効であることを示しているだけです: 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();
}
}