JAVA XML 使用 PKCS11 提供商 HSM 签名

JAVA XML Signature with PKCS11 provider HSM

我正在尝试使用我的 HSM 中的私钥签署 XML,但我收到错误消息,因为私钥包含 "sensitive" 信息,所以现在我'我正在尝试使用我的 PKCS11 提供商进行签名。

我正在使用 Luna JSP provider

我就是这样用私钥生成签名的在我的 HSM 中,但我不知道如何使用 XMLSignatureFactory.

来实现它
XMLSignatureFactory fac;
try {
  fac = XMLSignatureFactory.getInstance("DOM", (Provider) Class.forName(providerName).newInstance());
}
catch(InstantiationException | IllegalAccessException | ClassNotFoundException e) {
  e.printStackTrace();
}

Reference ref;
SignedInfo si;
try {
  ref = fac.newReference("",
                         fac.newDigestMethod(xmldss.getDigestMethod(), null),
                         Collections.singletonList(fac.newTransform(Transform.ENVELOPED,
                                                                    (TransformParameterSpec) null)),
                         null,
                         null);

  si = fac.newSignedInfo(fac.newCanonicalizationMethod(xmldss.getCanonicalizationMethod(),
                                                       (C14NMethodParameterSpec) null),
                         fac.newSignatureMethod(xmldss.getSignatureMethod(), null),
                         Collections.singletonList(ref));
}
catch(NoSuchAlgorithmException | InvalidAlgorithmParameterException e) {
  e.printStackTrace();
}

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
Document document;
try {
  document = (dbf.newDocumentBuilder().parse(xmlDocumentStream));
}
catch(SAXException | IOException | ParserConfigurationException e) {
  e.printStackTrace();
}

DOMSignContext dsc = new DOMSignContext(keyPair.getPrivate(), document.getDocumentElement());
dsc.setDefaultNamespacePrefix(xmldss.getDigitalSignerPrefix());

XMLSignature signature = fac.newXMLSignature(si, buildKeyInfo(fac, signatureInfos));
try {
  signature.sign(dsc);
}
catch(MarshalException | XMLSignatureException e) {
  e.printStackTrace();
}

深入研究 DOMXMLSignature 后,我发现 属性 org.jcp.xml.dsig.internal.dom.SignatureProvider 可用于设置提供商。

所以我的解决方法是

Provider lunaProvider = Security.getProvider("LunaProvider");
dsc.setProperty("org.jcp.xml.dsig.internal.dom.SignatureProvider", lunaProvider);