Java equivalent of C # XML Signing Method

I wrote the following .NET Framework 3.5 C # method, which accepts the location of an XML document and a representation of an X509 digital certificate object (with a private key) and returns the XML document as an object using an XML signature (XMLDsig) embedded as the first child root element.

The fact is that it is absolutely necessary for me to be able to perform the same procedure with Java SE 6, but I have not written any Java in the age and do not know where to start.

Can anyone provide an equivalent method in Java code that produces the same XML output?

private static XmlDocument SignXmlDocument(string xmlFilePath, X509Certificate2 certificate) { // load xml from disk preserving whitespaces XmlDocument xmlDocument = new XmlDocument { PreserveWhitespace = true }; xmlDocument.Load(xmlFilePath); // create signed xml with a same-document reference containing an enveloped-signature transform SignedXml signedXml = new SignedXml(xmlDocument) { SigningKey = certificate.PrivateKey }; Reference reference = new Reference { Uri = "" }; XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(env); signedXml.AddReference(reference); // embed public key information for signature validation purposes KeyInfo keyInfo = new KeyInfo(); KeyInfoX509Data keyInfoX509Data = new KeyInfoX509Data(certificate, X509IncludeOption.ExcludeRoot); keyInfo.AddClause(keyInfoX509Data); signedXml.KeyInfo = keyInfo; // compute and retreive the signature xml signedXml.ComputeSignature(); XmlElement xmldsigXmlElement = signedXml.GetXml(); // insert the signature xml into the xml document as first child of the root element xmlDocument.DocumentElement.PrependChild(xmlDocument.ImportNode(xmldsigXmlElement, true)); return xmlDocument; } 
+4
source share
3 answers

The following does the same in Java. This requires a PKCS12 certificate file on disk.

 import java.util.*; import java.io.*; import java.security.KeyStore; import java.security.KeyStore.PrivateKeyEntry; import java.security.cert.X509Certificate; import javax.xml.crypto.dsig.*; import javax.xml.crypto.dsig.dom.DOMSignContext; import javax.xml.crypto.dsig.keyinfo.*; import javax.xml.crypto.dsig.spec.*; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.*; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.w3c.dom.Document; public class XMLSigner { public static void signXmlDocumentOnDisk(String fileToBeSignedPath, String signedFileSavePath, String pkcs12CertificateFilePath, String password) throws Exception { XMLSignatureFactory fac = getXMLSignatureFactory(); Reference ref = getSHA1WholeDocumentEnvelopedTransformReference(fac); SignedInfo si = getSignedInfo(fac, ref); PrivateKeyEntry keyEntry = loadPKCS12KeyStoreAndGetSigningKeyEntry(pkcs12CertificateFilePath, password); KeyInfo ki = getKeyInfoWithX509Data(keyEntry, fac); Document doc = instantiateDocumentToBeSigned(fileToBeSignedPath); signDocumentAndPlaceSignatureAsFirstChildElement(doc, keyEntry, fac, si, ki); writeResultingDocument(doc, signedFileSavePath); } private static XMLSignatureFactory getXMLSignatureFactory() { return XMLSignatureFactory.getInstance("DOM"); } private static Reference getSHA1WholeDocumentEnvelopedTransformReference(XMLSignatureFactory fac) throws Exception { return fac.newReference( "", fac.newDigestMethod(DigestMethod.SHA1, null), Collections.singletonList(fac.newTransform(Transform.ENVELOPED, (TransformParameterSpec) null)), null, null ); } private static SignedInfo getSignedInfo(XMLSignatureFactory fac, Reference ref) throws Exception { return fac.newSignedInfo( fac.newCanonicalizationMethod( CanonicalizationMethod.INCLUSIVE, (C14NMethodParameterSpec) null ), fac.newSignatureMethod(SignatureMethod.RSA_SHA1, null), Collections.singletonList(ref) ); } private static PrivateKeyEntry loadPKCS12KeyStoreAndGetSigningKeyEntry(String pkcs12CertificateFilePath, String password) throws Exception { KeyStore ks = KeyStore.getInstance("PKCS12"); ks.load(new FileInputStream(pkcs12CertificateFilePath), password.toCharArray()); return (PrivateKeyEntry)ks.getEntry(ks.aliases().nextElement(), new KeyStore.PasswordProtection(password.toCharArray())); } private static KeyInfo getKeyInfoWithX509Data(PrivateKeyEntry keyEntry, XMLSignatureFactory fac) { X509Certificate cert = (X509Certificate) keyEntry.getCertificate(); KeyInfoFactory kif = fac.getKeyInfoFactory(); List x509Content = new ArrayList(); x509Content.add(cert.getSubjectX500Principal().getName()); x509Content.add(cert); X509Data xd = kif.newX509Data(x509Content); return kif.newKeyInfo(Collections.singletonList(xd)); } private static Document instantiateDocumentToBeSigned(String fileToBeSignedPath) throws Exception { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setNamespaceAware(true); return dbf.newDocumentBuilder().parse(new FileInputStream(fileToBeSignedPath)); } private static void signDocumentAndPlaceSignatureAsFirstChildElement(Document doc, PrivateKeyEntry keyEntry, XMLSignatureFactory fac, SignedInfo si, KeyInfo ki) throws Exception { DOMSignContext dsc = new DOMSignContext(keyEntry.getPrivateKey(), doc.getDocumentElement(), doc.getDocumentElement().getFirstChild()); XMLSignature signature = fac.newXMLSignature(si, ki); signature.sign(dsc); } private static void writeResultingDocument(Document doc, String signedFileSavePath) throws Exception { OutputStream os = new FileOutputStream(signedFileSavePath); TransformerFactory tf = TransformerFactory.newInstance(); Transformer trans = tf.newTransformer(); trans.transform(new DOMSource(doc), new StreamResult(os)); } } 
+4
source
0
source
 public static bool VerifyXml(string fileNFe) { //carregar o XML da NF-e XmlDocument xml = new XmlDocument(); xml.PreserveWhitespace = true; xml.Load(fileNFe); //pegar a Tag "NFe", à que contem assinatura dig. XmlNodeList nodeNFe = xml.GetElementsByTagName("NFe"); string NFe = nodeNFe[0].OuterXml.ToString(); //carregar o XML da NFe XmlDocument xmlNFe = new XmlDocument(); xmlNFe.PreserveWhitespace = true; xmlNFe.LoadXml(NFe); //Carregar a assinatura SignedXml signedXml = new SignedXml(xmlNFe); XmlNodeList nodeList = xmlNFe.GetElementsByTagName("Signature"); signedXml.LoadXml((XmlElement)nodeList[0]); //buscar o KeyInfo da assinatura IEnumerator keyInfoItems = signedXml.KeyInfo.GetEnumerator(); keyInfoItems.MoveNext(); KeyInfoX509Data keyInfoX509 = (KeyInfoX509Data)keyInfoItems.Current; //buscar o certificado do KeyInfo X509Certificate2 keyInfoCert = (X509Certificate2)keyInfoX509.Certificates[0]; //Validar se assinatura é valida bool isSigValid = signedXml.CheckSignature(keyInfoCert.PublicKey.Key); if (isSigValid) { MessageBox.Show("Assinatura digital é válida."); return true; } else { MessageBox.Show("Assinatura digital não é válida."); return false; } } 
-1
source

Source: https://habr.com/ru/post/979274/


All Articles