Verán, tengo el siguiente problema (por si acaso alguien puede ayudarme):
Tengo que realizar una firma XMLSignature usando la clase que viene en el paquete javax.xml.crypto.dsig (es decir, no puedo usar la clase de apache). Lo que es la firma la hago sin problemas. Se trata de una firma detached, por lo que el resultado sería algo como lo siguiente (he tenido que quitar las uris que aparecían, así que he dejado "comentado" las uris importantes):
Código:
Sin embargo, ahora necesito que el atributo URI del nodo Reference tenga un valor de URI "ficticio". Creo que se hace con el URIDereferencer que se puede establecer en el contexto DOMSignContext (método setURIDereferencer). Sin embargo, no sé muy bien como se haría. Creo que tengo que hacer una clase que implemente URIDereferencer y que cuando se le pase la URI falsa devuelva el contenido del documento, pero ni idea.<ds:Signature xmlns:ds="" Id="Signature1"> <ds:SignedInfo Id="Signature1-SignedInfo1"> <ds:CanonicalizationMethod Algorithm="" /> <ds:SignatureMethod Algorithm="rsa-sha1" /> <ds:Reference Id="Signature1-Reference1" URI="uriDelDocumento"> <ds:DigestMethod Algorithm="sha1" /> <ds:DigestValue>yqoGXlh5p6ZibMBO+T4gLK5If4E=</ds:DigestValue> </ds:Reference> </ds:SignedInfo> <ds:SignatureValue Id="Signature1-SignatureValue1">fdgRBXrnhqYZ9xXRhVfUv4r+tUPomXWfjaz9jqgIUSnDG4ngHt6hS3O43BDM7rpFRujioHGlZG4m uyEvy+6c5uKXk7w4xrFDvNtwR9K5/wuYgXj/8X5RSYYBGpC/Go4FwCA364+7pKkbb22cPMZZEHf0 7dmrhAPF1F/YcAc0xpA=</ds:SignatureValue> <ds:KeyInfo Id="Signature1-KeyInfo1"> <ds:X509Data> <ds:X509IssuerSerial> <ds:X509IssuerName>CN=testName, OU=testDepartment, O=testOrganization, L=testCity, ST=ES, C=38205 </ds:X509IssuerName> <ds:X509SerialNumber>150</ds:X509SerialNumber> </ds:X509IssuerSerial> <ds:X509Certificate>MIICuTCCAiKgAwIBAgICAJYwDQYJKoZIhvcNAQEFBQAwgZYxDjAMBgNVBAYTBTM4MjA1MQswCQYD VQQIDAJFUzERMA8GA1UEBwwIdGVzdENpdHkxGTAXBgNVBAoMEHRlc3RPcmdhbml6YXRpb24xFzAV BgNVBAsMDnRlc3REZXBhcnRtZW50MREwDwYDVQQDDAh0ZXN0TmFtZTEdMBsGCSqGSIb3DQEJARYO dGVzdEBlbWFpbC5jb20wHhcNMDkxMTE5MTQwOTAyWhcNMTExMTA5MTQwOTAyWjBRMTAwLgYDVQQD DCdETkkgMTIzNDU2NzhaIC0gQ2FybG9zIENvbG9tYSBFc2NyaWJhbm8xHTAbBgkqhkiG9w0BCQEW DnRlc3RAZW1haWwuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCIBGWxlBVarJHPvdcM WUXfq8AYPNGnwMiRnEPZP4rBFCbmKrz1RPadpb4cZqRd+krhp5K1jSsIqbi8J+bSu9f77X0WSrip C0vcPpi/eM41TKhh7a5oBvoKjez6HaOqZgC5DjMzTVy9PuGajhenIWKfn/rBeiTTzaV5o2199poj yQIDAQABo1owWDAdBgNVHQ4EFgQUtATC6atlP0g9PMLBlY0EGEzgUdMwHwYDVR0jBBgwFoAU0z7T ZlDCEkxUoHa3u6jXU7F1pKwwCQYDVR0TBAIwADALBgNVHQ8EBAMCBJAwDQYJKoZIhvcNAQEFBQAD gYEAXRJ1SkrzAxx26YHobYlcmc0I6C2d9J+GUVtn8jUSltx0ib+yvGh6LsusPKVmIwY054F88w7J BJk/sb7nEcjuBAjfeXzY0vA3Z7Hx8WaHrvlExuOGbP45avEuqsqzjnmgBS//e7u/XWgl897KA9xJ gGjjicKspj6LZizYArgorbc=</ds:X509Certificate> </ds:X509Data> <ds:KeyValue> <ds:RSAKeyValue> <ds:Modulus>iARlsZQVWqyRz73XDFlF36vAGDzRp8DIkZxD2T+KwRQm5iq89UT2naW+HGakXfpK4aeStY0rCKm4 vCfm0rvX++19Fkq4qQtL3D6Yv3jONUyoYe2uaAb6Co3s+h2jqmYAuQ4zM01cvT7hmo4XpyFin5/6 wXok082leaNtffaaI8k=</ds:Modulus> <ds:Exponent>AQAB</ds:Exponent> </ds:RSAKeyValue> </ds:KeyValue> </ds:KeyInfo> </ds:Signature>
Si alguien puede arrojar algo de luz al asunto lo agradecería enormemente
Dejo el código que genera la firma por si sirve de ayuda
Código:
Gracias de antemano!! XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM", (Provider) Class.forName(providerName).newInstance()); // Create a Reference to an external URI that will be digested // using the SHA1 digest algorithm Reference ref = fac.newReference(uriDocument, fac.newDigestMethod(DigestMethod.SHA1, null)); // Create the SignedInfo SignedInfo si = fac.newSignedInfo( fac.newCanonicalizationMethod (CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS, null), fac.newSignatureMethod(SignatureMethod.RSA_SHA1, null), Collections.singletonList(ref)); KeyStore ks = CertificatesUtil.loadKeyStore(), PrivateKey privateKey = (PrivateKey) ks.getKey(alias, pass.toCharArray()); X509Certificate cert = (X509Certificate) ks.getCertificate(alias); KeyInfoFactory kif = fac.getKeyInfoFactory(); X509IssuerSerial issuerSerial = kif.newX509IssuerSerial(cert.getIssuerDN().getName(), cert.getSerialNumber()); List<Object> x509DataContent = new ArrayList<Object>(); x509DataContent.add(issuerSerial); x509DataContent.add(cert); X509Data x509data = kif.newX509Data(x509DataContent); KeyValue keyValue = kif.newKeyValue(cert.getPublicKey()); List<Object> keyInfoContent = new ArrayList<Object>(); keyInfoContent.add(x509data); keyInfoContent.add(keyValue); KeyInfo ki = kif.newKeyInfo(keyInfoContent); // Create the XMLSignature (but don't sign it yet) XMLSignature signature = fac.newXMLSignature(si, ki); // Create the Document that will hold the resulting XMLSignature DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setNamespaceAware(true); // must be set Document doc = dbf.newDocumentBuilder().newDocument(); // Create a DOMSignContext and set the signing Key to the RSA // PrivateKey and specify where the XMLSignature should be inserted // in the target document (in this case, the document root) DOMSignContext signContext = new DOMSignContext(privateKey, doc); signContext.setDefaultNamespacePrefix("ds"); // Marshal, generate (and sign) the detached XMLSignature. The DOM // Document will contain the XML Signature if this method returns // successfully. signature.sign(signContext);