|
View:
New views
1 Messages
—
Rating Filter:
Alert me
|
|
|
questionI have been trying to sign an XML file using the apache security package. I seem to be able to verify the signature on my side but it cannot be verified on the client side. What I can explain is why the CanonicalizationMethod Algorithim is "http://www.w3.org/TR/2001/REC-xml-c14n-20010315" <ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"/> but the Transform Algorithm is "http://www.w3.org/2001/10/xml-exc-c14n#" <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"/> Below is the output file followed by the java code and the keystore used. Please comment the code if you wish. I am not quite sure what I am doing here Here is the output xml file: <?xml version="1.0" encoding="UTF-8"?> <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <s:Header> <Security s:actor="IntervenantEmetteur" xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <ds:SignedInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"/> <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"/> <ds:Reference URI="#PJC_01" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <ds:Transforms xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"/> </ds:Transforms> <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"/> <ds:DigestValue xmlns:ds="http://www.w3.org/2000/09/xmldsig#">oNbIWOzgYk4X9634QnN5uA4bTHc=</ds:DigestValue> </ds:Reference> </ds:SignedInfo> <ds:SignatureValue xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> pohyKWQgfhSNe1BC/QJbR/CsDP8hSaJyQeoyJJ6TYkDa4xs7UznQV+heP/lK7zQH3jRaGO61OxhB +rHpIVlYHl2vHRBCp6+dWu+e2/e16DfMOz2zb9K55+24GhOP3wo26riduDWg6BGQeKGCwLxyvn3r KIe3nU/00hc4f/duh4M= </ds:SignatureValue> <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <ds:X509Data xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <ds:X509Certificate xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> MIIB6jCCAVMCBEeCcWUwDQYJKoZIhvcNAQEEBQAwPDELMAkGA1UEBhMCQ0ExDDAKBgNVBAoTA1BK QzERMA8GA1UECxMIQ2VudHJlUngxDDAKBgNVBAMTA0pDTDAeFw0wODAxMDcxODM3MjVaFw0wODA0 MDYxODM3MjVaMDwxCzAJBgNVBAYTAkNBMQwwCgYDVQQKEwNQSkMxETAPBgNVBAsTCENlbnRyZVJ4 MQwwCgYDVQQDEwNKQ0wwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOQWVGHiDaV7lcDNWhZy L2+nR66VAjgryXio6wh4dhuqTU+XSAcSlpTSUh6OBcScTQsKvqci3O3rfUpYh0l6WC6vBOb9M1Rh MDne6NmUtEx2LP/iJkutob+joO08LKx4g73NMuPgjlYVRMfXvFb92mzgBuxpM0RyctcDeNazayCP AgMBAAEwDQYJKoZIhvcNAQEEBQADgYEAi216ZxtAIOxZgIpDUfAyElsPTKEt/FKmmX90DgNeQNt4 zGWeJZJKwlnFkxfa0U64puTPw6BZscBCUhkzRUpzPT0Rxc5iPaGnq9xPiYsf8T3Uqx5+bD++em9z nEKBTfKd7mM6JQAKKq7wlcYsKHcfupsHITRnYmPJ0F+fLVY/B4Y= </ds:X509Certificate> </ds:X509Data> <ds:KeyValue xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <ds:RSAKeyValue xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <ds:Modulus xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> 5BZUYeINpXuVwM1aFnIvb6dHrpUCOCvJeKjrCHh2G6pNT5dIBxKWlNJSHo4FxJxNCwq+pyLc7et9 SliHSXpYLq8E5v0zVGEwOd7o2ZS0THYs/+ImS62hv6Og7TwsrHiDvc0y4+COVhVEx9e8Vv3abOAG 7GkzRHJy1wN41rNrII8= </ds:Modulus> <ds:Exponent xmlns:ds="http://www.w3.org/2000/09/xmldsig#">AQAB</ds:Exponent> </ds:RSAKeyValue> </ds:KeyValue> </ds:KeyInfo> </ds:Signature></Security> </s:Header> <s:Body Id="PJC_01"> Some text to sign. </s:Body> </s:Envelope> Java code: import java.io.ByteArrayInputStream; import java.io.FileInputStream; import java.io.FileWriter; import java.io.StringReader; import java.io.StringWriter; import java.security.KeyStore; import java.security.PrivateKey; import java.security.cert.X509Certificate; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.Result; import javax.xml.transform.Source; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.apache.xml.security.signature.XMLSignature; import org.apache.xml.security.signature.XMLSignatureInput; import org.apache.xml.security.transforms.Transforms; import org.apache.xml.security.utils.Constants; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; public class SignXMLDetached { /** {@link org.apache.commons.logging} logging facility */ static org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(SignXMLDetached.class.getName()); // Name of the output file. private static final String OUTPUT_FILE_NAME = "signature.xml"; // All the parameters for the keystore (RSA) private String keystoreType = "JKS"; private String algoSignature = XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA1; /** * This is sample test. It call the method that will sign an XML * document represented as a Striong object. * * @param unused Arguments are for main signature but are not used. * @throws Exception If any of the exception are encountered such * as file not found, xml parsing errors, xml signature error, etc... */ public static void main(String unused[]) throws Exception { String keystorePass = "ab987c"; String privateKeyAlias = "test"; String privateKeyPass = "kpi135"; String keystoreFile = "keystore/pjc.jks"; String xmlStream = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +"<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n" +"<s:Header>\n" +" <Security s:actor=\"IntervenantEmetteur\" xmlns=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\">\n" +" </Security>\n" +"</s:Header>\n" +"<s:Body Id=\"PJC_01\">\n" +"Some text to sign." +" </s:Body>\n" +"</s:Envelope>\n"; SignXMLDetached signXml = new SignXMLDetached(); String signedXML = signXml.signIt(keystoreFile, keystorePass, privateKeyAlias, privateKeyPass, xmlStream); FileWriter out = new FileWriter(OUTPUT_FILE_NAME); out.write(signedXML); out.flush(); out.close(); System.out.println("Finished signing. View file in '"+ OUTPUT_FILE_NAME +"'."); } /** * This method create an XML document using the given String object. * Then we transform (normalize) add key information and sign the XML * document. Finally we convert document to a String object that represents the XML document. * @param keyStorePath : name and location of the keystore file. * @param keystorePass : the password to open keystore. * @param privateKeyAlias : the private key and certificate alias as stored inside the keystore. * @param privateKeyPass : the private key password needed to retrieve private key. * @param strXML : A String object that represents the XML document to sign. * @return Returns a String representing the sign XML document. * @throws Exception If any of the exception are encountered such * as file not found, xml parsing errors, xml signature error, etc... */ public String signIt(String keyStorePath, String keystorePass, String privateKeyAlias, String privateKeyPass, String strXML) throws Exception { org.apache.xml.security.Init.init(); KeyStore ks = KeyStore.getInstance(keystoreType); FileInputStream fis = new FileInputStream(keyStorePath); // Load the keystore information. ks.load(fis, keystorePass.toCharArray()); // Get the private key from keystore (will be used for signing). PrivateKey privateKey = (PrivateKey) ks.getKey(privateKeyAlias, privateKeyPass.toCharArray()); // Create a document factory to build the xml file to sign. javax.xml.parsers.DocumentBuilderFactory dbf = javax.xml.parsers.DocumentBuilderFactory.newInstance(); // XML Signature needs to be namespace aware dbf.setNamespaceAware(true); // Create XML document using given string (that represents the xml document). javax.xml.parsers.DocumentBuilder db = dbf.newDocumentBuilder(); org.w3c.dom.Document doc = db.parse(new InputSource(new StringReader(strXML))); NodeList nodeList = doc.getElementsByTagName("Security"); Node root = nodeList.item(0); // Create the transforms object for the Document/Reference Transforms transforms = new Transforms(doc); // Canonicalized part of the signature element. transforms.addTransform(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS); // Create an XML Signature object from the document. String baseURI = null; XMLSignature sig = new XMLSignature(doc, baseURI, algoSignature); // Add the above Document/Reference to signature. // The signature is going to be injected inside the root node. root.appendChild(sig.getElement()); sig.addDocument("#PJC_01", transforms, Constants.ALGO_ID_DIGEST_SHA1); // Get the certificate from keystore. Then add it in the KeyInfo element // along with the public key. Note, this could have its own alias but // we will considered it to be the same as the private key alias. X509Certificate cert = (X509Certificate) ks.getCertificate(privateKeyAlias); sig.addKeyInfo(cert); sig.addKeyInfo(cert.getPublicKey()); sig.sign(privateKey); // Convert XML Doc to String. return xmlToString(doc); } /* * Convert the given xml Document object to a String object. * If an error occurs, log it and return a null object. * * @param doc : A Document object to convert to a String object. * @return Returns a String object representing the given Document object. */ private static String xmlToString(org.w3c.dom.Document doc) { try { Source source = new DOMSource(doc); StringWriter stringWriter = new StringWriter(); Result result = new StreamResult(stringWriter); TransformerFactory factory = TransformerFactory.newInstance(); Transformer transformer = factory.newTransformer(); transformer.transform(source, result); return stringWriter.getBuffer().toString(); } catch (TransformerConfigurationException e) { e.printStackTrace(); } catch (TransformerException e) { e.printStackTrace(); } return null; } } Jean-Charles Laurent Analyste / Analyst Le Groupe Jean Coutu (PJC) Inc. tél: 450-463-1890 (3363) fax: 450-646-0567 jclaurent@...
|
| Free Forum Powered by Nabble | Forum Help |