如何使用JAVA在XML中添加多个签名
我有以下方法,使用JDom库、Apache XML安全库、org.w3c.dom包和java.Security包使用单个PFX证书中的数据对单个XML文件进行签名:如何使用JAVA在XML中添加多个签名,java,xml,x509certificate,jdom,Java,Xml,X509certificate,Jdom,我有以下方法,使用JDom库、Apache XML安全库、org.w3c.dom包和java.Security包使用单个PFX证书中的数据对单个XML文件进行签名: /** This method allows to sign a single XML using data from a single Certificate and a given Namespace @param pKey Private Key obtained from a PFX certificate @param
/** This method allows to sign a single XML using data from a single Certificate and a given Namespace
@param pKey Private Key obtained from a PFX certificate
@param cert Certificate data obtained from the PFX file
@param ns Namespace to be associated to the root tag of the signed XML content
**/
public void sign(PrivateKey pKey, X509Certificate cert, Namespace ns) throws JDOMException,
InvalidKeyException, NoSuchAlgorithmException, SignatureException, XMLSecurityException,
ParserConfigurationException, IOException, SAXException, DTECedidoException, TimbreException, CodigoException, ReciboException {
Constants.setSignatureSpecNSprefix("");
String baseUri = null;
if (ns != null)
baseUri = ns.getURI();
String alg = pKey.getAlgorithm();
if (!alg.equals(cert.getPublicKey().getAlgorithm()))
throw (new DTECedidoException(DTECedidoException.NOT_CORRESPONDING));
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db = dbf.newDocumentBuilder();
ByteArrayOutputStream out = new ByteArrayOutputStream();
XMLUtil.getNiceXML(genDocument(ns), out);
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
org.w3c.dom.Document doc = db.parse(in);
org.w3c.dom.Element root = doc.getDocumentElement();
XMLSignature sig = null;
if (alg.equals("RSA")) {
if (!((RSAPrivateKey) pKey).getModulus().equals(((RSAPublicKey) cert.getPublicKey()).getModulus()))
throw (new DTECedidoException(DTECedidoException.NOT_CORRESPONDING));
sig = new XMLSignature(doc, baseUri, XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA1);
} else if (alg.equals("DSA")) {
if (!(((DSAPrivateKey) pKey).getParams().getG()
.equals(((DSAPublicKey) cert.getPublicKey()).getParams().getG())
&& ((DSAPrivateKey) pKey).getParams().getP()
.equals(((DSAPublicKey) cert.getPublicKey()).getParams().getP())
&& ((DSAPrivateKey) pKey).getParams().getQ()
.equals(((DSAPublicKey) cert.getPublicKey()).getParams().getQ())))
throw (new DTECedidoException(DTECedidoException.NOT_CORRESPONDING));
sig = new XMLSignature(doc, baseUri, XMLSignature.ALGO_ID_SIGNATURE_DSA);
} else
throw (new DTECedidoException(DTECedidoException.NOT_CORRESPONDING));
root.appendChild(sig.getElement());
sig.addDocument("#" + getId());
X509Data xdata = new X509Data(doc);
xdata.addCertificate(cert);
sig.getKeyInfo().addKeyValue(cert.getPublicKey());
sig.getKeyInfo().add(xdata);
sig.sign(pKey);
ByteArrayOutputStream bous = new ByteArrayOutputStream();
DOMBuilder docIn = new DOMBuilder();
Document domdoc = docIn.build(doc);
cl.sii.dte.util.XMLUtil.getNiceXML(domdoc, bous);
this.signedDoc = bous.toByteArray();
}
这种方法效果很好。但是,我需要重载它,新方法必须支持来自多个证书的数据(最多3个)。到目前为止,我有:
/** This method allows to sign a single XML using data from multiples Certificates and a given Namespace
@param pKey List of Private Keys obtained from one PFX certificate per key
@param cert List of Certificate datas obtained from one PFX file per data.
@param ns Namespace to be associated to the root tag of the signed XML content
**/
public void sign(List<PrivateKey> pKey, List<X509Certificate> cert, Namespace ns) throws JDOMException,
InvalidKeyException, NoSuchAlgorithmException, SignatureException, XMLSecurityException,
ParserConfigurationException, IOException, SAXException, DTECedidoException, TimbreException, CodigoException, ReciboException {
/* Loads the unsigned XML ENTIRE content in order to add the signatures*/
Constants.setSignatureSpecNSprefix("");
String baseUri = null;
if (ns != null)
baseUri = ns.getURI();
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db = dbf.newDocumentBuilder();
ByteArrayOutputStream out = new ByteArrayOutputStream();
XMLUtil.getNiceXML(genDocument(ns), out);
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
org.w3c.dom.Document doc = db.parse(in);
org.w3c.dom.Element root = doc.getDocumentElement();
XMLSignature sig = null;
for(int i=0; i<pKey.size(); i++){
PrivateKey pk=pKey.get(i);
X509Certificate c=cert.get(i)
String alg = pk.getAlgorithm();
if (!alg.equals(c.getPublicKey().getAlgorithm()))
throw (new DTECedidoException(DTECedidoException.NOT_CORRESPONDING));
if (alg.equals("RSA")) {
if (!((RSAPrivateKey) pk).getModulus().equals(((RSAPublicKey) c.getPublicKey()).getModulus()))
throw (new DTECedidoException(DTECedidoException.NOT_CORRESPONDING));
sig = new XMLSignature(doc, baseUri, XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA1);
} else if (alg.equals("DSA")) {
if (!(((DSAPrivateKey) pk).getParams().getG()
.equals(((DSAPublicKey) c.getPublicKey()).getParams().getG())
&& ((DSAPrivateKey) pk).getParams().getP()
.equals(((DSAPublicKey) c.getPublicKey()).getParams().getP())
&& ((DSAPrivateKey) pk).getParams().getQ()
.equals(((DSAPublicKey) c.getPublicKey()).getParams().getQ())))
throw (new DTECedidoException(DTECedidoException.NOT_CORRESPONDING));
sig = new XMLSignature(doc, baseUri, XMLSignature.ALGO_ID_SIGNATURE_DSA);
} else
throw (new DTECedidoException(DTECedidoException.NOT_CORRESPONDING));
root.appendChild(sig.getElement());
sig.addDocument("#" + getId());
/* The following lines of code give me problems*/
X509Data xdata = new X509Data(doc);
xdata.addCertificate(c);
sig.getKeyInfo().addKeyValue(c.getPublicKey());
sig.getKeyInfo().add(xdata);
sig.sign(pk);
}
/* Generates and stores the byte content of the resulting
signed XML */
ByteArrayOutputStream bous = new ByteArrayOutputStream();
DOMBuilder docIn = new DOMBuilder();
Document domdoc = docIn.build(doc);
cl.sii.dte.util.XMLUtil.getNiceXML(domdoc, bous);
this.signedDoc = bous.toByteArray();
}
我在哪里可以找到一个很好的例子,使用来自多个使用Java的PFX文件的信息对XML文件进行签名(我自己尝试了,但没有成功)
提前谢谢
编辑
我同时提出了这个方法,希望这是正确的方法
public void sign(List<PrivateKey> pKey, List<X509Certificate> cert, Namespace ns)
throws XMLSecurityException, ParserConfigurationException, SAXException, IOException, CesionException {
Constants.setSignatureSpecNSprefix("");
String baseUri = null;
if (ns != null)
baseUri = ns.getURI();
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db = dbf.newDocumentBuilder();
ByteArrayOutputStream out = new ByteArrayOutputStream();
XMLUtil.getNiceXML(genDocument(ns), out);
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
org.w3c.dom.Document doc = db.parse(in);
org.w3c.dom.Element root = doc.getDocumentElement();
XMLSignature sig = null;
for(int i=0; i<pKey.size(); i++) {
PrivateKey pk=pKey.get(i);
X509Certificate c=cert.get(i);
String alg = pk.getAlgorithm();
if (!alg.equals(c.getPublicKey().getAlgorithm()))
throw (new CesionException(CesionException.NOT_CORRESPONDING));
if (alg.equals("RSA")) {
if (!((RSAPrivateKey) pk).getModulus().equals(((RSAPublicKey) c.getPublicKey()).getModulus()))
throw (new CesionException(CesionException.NOT_CORRESPONDING));
sig = new XMLSignature(doc, baseUri, XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA1);
} else if (alg.equals("DSA")) {
if (!(((DSAPrivateKey) pk).getParams().getG()
.equals(((DSAPublicKey) c.getPublicKey()).getParams().getG())
&& ((DSAPrivateKey) pk).getParams().getP()
.equals(((DSAPublicKey) c.getPublicKey()).getParams().getP())
&& ((DSAPrivateKey) pk).getParams().getQ()
.equals(((DSAPublicKey) c.getPublicKey()).getParams().getQ())))
throw (new CesionException(CesionException.NOT_CORRESPONDING));
sig = new XMLSignature(doc, baseUri, XMLSignature.ALGO_ID_SIGNATURE_DSA);
} else
throw (new CesionException(DTECedidoException.NOT_CORRESPONDING));
root.appendChild(sig.getElement());
sig.addDocument("#" + i);
X509Data xdata = new X509Data(doc);
xdata.addCertificate(c);
sig.getKeyInfo().addKeyValue(c.getPublicKey());
sig.getKeyInfo().add(xdata);
sig.sign(pk);
}
ByteArrayOutputStream bous = new ByteArrayOutputStream();
DOMBuilder docIn = new DOMBuilder();
Document domdoc = docIn.build(doc);
cl.sii.dte.util.XMLUtil.getNiceXML(domdoc, bous);
this.signedDoc = bous.toByteArray();
}
public void sign(列表pKey、列表证书、命名空间ns)
抛出XMLSecurityException、ParserConfiguration异常、SAXException、IOException、CesionException{
常量。SetSignatureSpecInsprefix(“”);
字符串baseUri=null;
如果(ns!=null)
baseUri=ns.getURI();
DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db=dbf.newDocumentBuilder();
ByteArrayOutputStream out=新建ByteArrayOutputStream();
getNiceXML(genDocument(ns),out);
ByteArrayInputStream in=新的ByteArrayInputStream(out.toByteArray());
org.w3c.dom.Document doc=db.parse(in);
org.w3c.dom.Element root=doc.getDocumentElement();
XMLSignature sig=null;
对于(int i=0;i
public void sign(List<PrivateKey> pKey, List<X509Certificate> cert, Namespace ns)
throws XMLSecurityException, ParserConfigurationException, SAXException, IOException, CesionException {
Constants.setSignatureSpecNSprefix("");
String baseUri = null;
if (ns != null)
baseUri = ns.getURI();
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db = dbf.newDocumentBuilder();
ByteArrayOutputStream out = new ByteArrayOutputStream();
XMLUtil.getNiceXML(genDocument(ns), out);
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
org.w3c.dom.Document doc = db.parse(in);
org.w3c.dom.Element root = doc.getDocumentElement();
XMLSignature sig = null;
for(int i=0; i<pKey.size(); i++) {
PrivateKey pk=pKey.get(i);
X509Certificate c=cert.get(i);
String alg = pk.getAlgorithm();
if (!alg.equals(c.getPublicKey().getAlgorithm()))
throw (new CesionException(CesionException.NOT_CORRESPONDING));
if (alg.equals("RSA")) {
if (!((RSAPrivateKey) pk).getModulus().equals(((RSAPublicKey) c.getPublicKey()).getModulus()))
throw (new CesionException(CesionException.NOT_CORRESPONDING));
sig = new XMLSignature(doc, baseUri, XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA1);
} else if (alg.equals("DSA")) {
if (!(((DSAPrivateKey) pk).getParams().getG()
.equals(((DSAPublicKey) c.getPublicKey()).getParams().getG())
&& ((DSAPrivateKey) pk).getParams().getP()
.equals(((DSAPublicKey) c.getPublicKey()).getParams().getP())
&& ((DSAPrivateKey) pk).getParams().getQ()
.equals(((DSAPublicKey) c.getPublicKey()).getParams().getQ())))
throw (new CesionException(CesionException.NOT_CORRESPONDING));
sig = new XMLSignature(doc, baseUri, XMLSignature.ALGO_ID_SIGNATURE_DSA);
} else
throw (new CesionException(DTECedidoException.NOT_CORRESPONDING));
root.appendChild(sig.getElement());
sig.addDocument("#" + i);
X509Data xdata = new X509Data(doc);
xdata.addCertificate(c);
sig.getKeyInfo().addKeyValue(c.getPublicKey());
sig.getKeyInfo().add(xdata);
sig.sign(pk);
}
ByteArrayOutputStream bous = new ByteArrayOutputStream();
DOMBuilder docIn = new DOMBuilder();
Document domdoc = docIn.build(doc);
cl.sii.dte.util.XMLUtil.getNiceXML(domdoc, bous);
this.signedDoc = bous.toByteArray();
}