package com.r_bg.stax; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.math.BigInteger; import java.security.Key; import java.security.KeyFactory; import java.security.KeyStore; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.spec.RSAPublicKeySpec; import javax.xml.crypto.XMLStructure; import javax.xml.crypto.dsig.Reference; import javax.xml.crypto.dsig.XMLSignature; import javax.xml.crypto.dsig.XMLSignatureFactory; import javax.xml.crypto.dsig.XMLValidateContext; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; import org.apache.xml.security.Init; import org.apache.xml.security.c14n.Canonicalizer; import org.apache.xml.security.signature.ObjectContainer; import org.apache.xml.security.transforms.Transforms; import org.apache.xml.security.utils.Base64; import org.apache.xml.security.utils.XMLUtils; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.xml.sax.SAXException; import sun.security.rsa.RSAKeyFactory; import sun.security.rsa.RSAPrivateKeyImpl; import junit.framework.TestCase; public class XMLSignatureTest extends TestCase { static Key getKey() throws Exception { byte[] modulus=Base64.decode("skqbW7oBwM1lCWNwC1obkgj4VV58G1AX7ERMWEIrQQlZ8uFdQ3FNkgMdtmx/XUjNF+zXTDmxe+K/\n" + "lne+0KDwLWskqhS6gnkQmxZoR4FUovqRngoqU6bnnn0pM9gF/AI/vcdu7aowbF9S7TVlSw7IpxIQ\n" + "VjevEfohDpn/+oxljm0=\n"); byte[] exponent=Base64.decode("AQAB"); RSAPublicKeySpec spec=new RSAPublicKeySpec(new BigInteger(1,modulus),new BigInteger(1,exponent)); return KeyFactory.getInstance("rsa").generatePublic(spec); } static PrivateKey obtainPrivateKey() throws Exception { KeyStore ks = KeyStore.getInstance("JKS"); FileInputStream fis = new FileInputStream("keystore.jks"); ks.load(fis, "secret".toCharArray()); return (PrivateKey) ks.getKey("tfc", "secret".toCharArray()); } static PublicKey obtainPublicKey() throws Exception { KeyStore ks = KeyStore.getInstance("JKS"); FileInputStream fis = new FileInputStream("keystore.jks"); ks.load(fis, "secret".toCharArray()); return ks.getCertificate("tfc").getPublicKey(); } static String generateSignature(int size,String name) throws Exception{ DocumentBuilderFactory fact=DocumentBuilderFactory.newInstance(); fact.setNamespaceAware(true); Document doc=fact.newDocumentBuilder().newDocument(); org.apache.xml.security.signature.XMLSignature sig=new org.apache.xml.security.signature.XMLSignature(doc,"", org.apache.xml.security.signature.XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA1, Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS); Transforms trs=new Transforms(doc); trs.addTransform(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS); sig.addDocument("#1",trs); doc.appendChild(sig.getElement()); ObjectContainer ob=new ObjectContainer(doc); ob.setId("1"); sig.appendObject(ob); sig.addKeyInfo(obtainPublicKey()); for (int i=0;i\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "oMQoFufPA7Un6cfz0GaEOJpE4Z8=\n" + "\n" + "\n" + "\n" + "AhyiFQ6hucykYJOJDBV3wbPBe2TAURXXfCUD7BmSAecT+izT9fHFsxRVez3s+6hYSgtaVhmeVgbd\n" + "ZEOMPFihBGldi1NV73Z/tpXxqNvY+/NwQmmasQp9gzFHxYF2cqi8m7sAHM03BIC1YoBctxVw/jxV\n" + "ClhLJuTSHoKwlzKH24g=\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "skqbW7oBwM1lCWNwC1obkgj4VV58G1AX7ERMWEIrQQlZ8uFdQ3FNkgMdtmx/XUjNF+zXTDmxe+K/\n" + "lne+0KDwLWskqhS6gnkQmxZoR4FUovqRngoqU6bnnn0pM9gF/AI/vcdu7aowbF9S7TVlSw7IpxIQ\n" + "VjevEfohDpn/+oxljm0=\n" + "\n" + "AQAB\n" + "\n" + "\n" + "\n" + "A text in a box\n" + ""; XMLInputFactory im=XMLInputFactory.newInstance(); im.setProperty("javax.xml.stream.supportDTD", new Boolean(false)); XMLStreamReader reader=im.createXMLStreamReader(new ByteArrayInputStream(in.getBytes())); StaxValidateContext stx = StaxValidateContext.createEnvolopedValidator(getKey(),reader); reader=im.createFilteredReader(reader, stx.getStreamFilter()); while ((reader.getEventType())!=XMLStreamReader.END_DOCUMENT) { reader.next(); } XMLSignatureFactory fac=XMLSignatureFactory.getInstance("Stax", new com.r_bg.stax.StaxProvider()); stx.setSignatureNumber(0); XMLSignature sig=fac.unmarshalXMLSignature(stx); if (!((Reference)sig.getSignedInfo().getReferences().get(0)).validate(stx)) { //Firma invalida. } //generateSignature(262144/34,"Enveloped1MB.xml"); assertTrue("Signature References must be right", ((Reference)sig.getSignedInfo().getReferences().get(0)).validate(stx)); assertTrue("Signature must be right", sig.validate(stx)); } public void testTamperedEnvelopedSignature() throws Exception { String in="\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "oMQoFufPA7Un6cfz0GaEOJpE4Z8=\n" + "\n" + "\n" + "\n" + "AhyiFQ6hucykYJOJDBV3wbPBe2TAURXXfCUD7BmSAecT+izT9fHFsxRVez3s+6hYSgtaVhmeVgbd\n" + "ZEOMPFihBGldi1NV73Z/tpXxqNvY+/NwQmmasQp9gzFHxYF2cqi8m7sAHM03BIC1YoBctxVw/jxV\n" + "ClhLJuTSHoKwlzKH24g=\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "skqbW7oBwM1lCWNwC1obkgj4VV58G1AX7ERMWEIrQQlZ8uFdQ3FNkgMdtmx/XUjNF+zXTDmxe+K/\n" + "lne+0KDwLWskqhS6gnkQmxZoR4FUovqRngoqU6bnnn0pM9gF/AI/vcdu7aowbF9S7TVlSw7IpxIQ\n" + "VjevEfohDpn/+oxljm0=\n" + "\n" + "AQAB\n" + "\n" + "\n" + "\n" + "a text in a box\n" + ""; XMLInputFactory im=XMLInputFactory.newInstance(); im.setProperty("javax.xml.stream.supportDTD", new Boolean(false)); XMLStreamReader reader=im.createXMLStreamReader(new ByteArrayInputStream(in.getBytes())); StaxValidateContext stx = StaxValidateContext.createEnvolopedValidator(getKey(),reader); reader=im.createFilteredReader(reader, stx.getStreamFilter()); while ((reader.getEventType())!=XMLStreamReader.END_DOCUMENT) { reader.next(); } XMLSignatureFactory fac=XMLSignatureFactory.getInstance("Stax", new com.r_bg.stax.StaxProvider() ); stx.setSignatureNumber(0); XMLSignature sig=fac.unmarshalXMLSignature(stx); assertFalse("Signature must be wrong", ((Reference)sig.getSignedInfo().getReferences().get(0)).validate(stx)); assertFalse("Signature must be false", sig.validate(stx)); } final static String ALUMNO_NS="http://fi.upm.es/alumnos/1/0"; public void atestParsing() throws Exception { XMLInputFactory im=XMLInputFactory.newInstance(); im.setProperty("javax.xml.stream.supportDTD", new Boolean(false)); XMLStreamReader reader=im.createXMLStreamReader(new FileInputStream("alumnoEnveloped.xml")); StaxValidateContext stx = StaxValidateContext.createEnvolopedValidator(getKey(),reader); reader=im.createFilteredReader(reader, stx.getStreamFilter()); String nombre=null; String apellidos=null; do { if (reader.getEventType()==XMLStreamReader.START_ELEMENT) { if (!ALUMNO_NS.equals(reader.getNamespaceURI())) continue; if ("Nombre".equals(reader.getLocalName())) { reader.next(); nombre=reader.getText(); continue; } if ("Apellidos".equals(reader.getLocalName())) { reader.next(); apellidos=reader.getText(); continue; } } reader.next(); } while ((reader.getEventType())!=XMLStreamReader.END_DOCUMENT); System.out.println("Nombre: "+nombre+" Apellidos:"+apellidos); XMLSignatureFactory fac=XMLSignatureFactory.getInstance("Stax", new com.r_bg.stax.StaxProvider()); stx.setSignatureNumber(0); XMLSignature sig=fac.unmarshalXMLSignature(stx); if (!sig.validate(stx)) { //Firma invalida. System.out.println("Firma Invalida"); } } static { Init.init(); StaxXMLSignatureFactory.getInstance("Stax", new StaxProvider()); }; }