entre Desarrolladores

Recibe ayuda de expertos

Registrate y pregunta

Es gratis y fácil

Recibe respuestas

Respuestas, votos y comentarios

Vota y selecciona respuestas

Recibe puntos, vota y da la solución

Pregunta

1voto

Java 7 - Generar Cadena Original - Generar Sello para CFDI SAT 3.3

Saludos!

Estoy realizando una aplicación java para realizar facturas.

Ya está todo realizado, pero al parecer el problema que tengo es al momento de realizar la cadena original y el sellado.

Me marca el SAT el siguiente error

Descripción: La firma digital (sello) del emisor del documento no es válida.

Sugerencia: El documento fue firmado con una clave privada que no corresponde al certificado; o el documento fue alterado en términos de algoritmo de c14n (cadena original u otro).

Mi código es el siguiente:

DocumentBuilderFactory cfdiFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder cfdiBuilder = cfdiFactory.newDocumentBuilder();
Document cfdi = cfdiBuilder.newDocument();
Element comprobante = cfdi.createElement( "cfdi:Comprobante" );
...
...
...
cfdi.appendChild( comprobante );
/*XML Terminado sin TIMBRAR*/
Random rand = new Random();
int  n = rand.nextInt(50) + 1;
/*NumeroRandom para crear archivo temporal y poder hacer CadenaOriginal*/
File xslt = new File("cadenaoriginal-3_3xslt/cadenaoriginal_3_3.xslt");
StreamSource sourceXSL = new StreamSource(xslt);
/*XSLT para formar CadenaOriginal*/
DOMSource source = new DOMSource(cfdi);
FileWriter writer = new FileWriter(new File(Funcion.rutaArchivos + "Temp/temp" + n + ".xml"));
StreamResult sourceXML = new StreamResult(writer);
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.transform(source, sourceXML);
/*CFDI Temporal*/
ByteArrayOutputStream bos=new ByteArrayOutputStream();
StreamResult cadenaOriginal = new StreamResult(bos);
File xmlFile = new File(Funcion.rutaArchivos + "Temp/temp" + n + ".xml");
StreamSource sourceXML2 = new StreamSource(xmlFile);
TransformerFactory tFactory = TransformerFactory.newInstance();
Transformer transformer2 = tFactory.newTransformer(sourceXSL);
transformer2.transform(sourceXML2, cadenaOriginal);
/*Cadena Original*/
Path path = Paths.get(rutaKey);
byte[] keyBytes = Files.readAllBytes(path);
// String keyString = new String(keyBytes, StandardCharsets.UTF_8);
PKCS8Key pkcs8 = new PKCS8Key(keyBytes, p4ss.toCharArray());
KeyFactory privateKeyFactory = KeyFactory.getInstance("RSA");
PKCS8EncodedKeySpec pkcs8Encoded = new PKCS8EncodedKeySpec(pkcs8.getDecryptedBytes());
PrivateKey privateKey = privateKeyFactory.generatePrivate(pkcs8Encoded);
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initSign(privateKey);
byte[] cadenaOriginalArray = bos.toByteArray();
signature.update(cadenaOriginalArray);
String firma = DatatypeConverter.printBase64Binary(cadenaOriginalArray);
System.out.println("------------------ Cadena Original: " + bos.toString());
System.out.println("---------Firma: " + firma);

¿Alguien ve algo extraño?

Gracias!!!

1 Respuesta

1voto

Th3Mik3s Puntos430

Saludos, por si alguien ocupa después

cfdi.appendChild( comprobante );
//XML Terminado sin TIMBRAR
int n = new Random().nextInt(50) + 1;
//NumeroRandom para crear archivo temporal y poder hacer CadenaOriginal
File xslt = new File("Timbrado/cadenaoriginal-3_3xslt/cadenaoriginal_3_3.xslt");
StreamSource sourceXSL = new StreamSource(xslt);
//XSLT para formar CadenaOriginal
DOMSource source = new DOMSource(cfdi);
FileWriter writer = new FileWriter(new File(Funcion.rutaArchivos + "Temp/temp" + n + ".xml"));
StreamResult sourceXML = new StreamResult(writer);
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.transform(source, sourceXML);
//CFDI Temporal
ByteArrayOutputStream bos=new ByteArrayOutputStream();
StreamResult cadenaOriginal = new StreamResult(bos);
File xmlFile = new File(Funcion.rutaArchivos + "Temp/temp" + n + ".xml");
StreamSource sourceXML2 = new StreamSource(xmlFile);
TransformerFactory tFactory = TransformerFactory.newInstance();
Transformer transformer2 = tFactory.newTransformer(sourceXSL);
transformer2.transform(sourceXML2, cadenaOriginal);
//Cadena Original
File keyFile = new File(rutaKey);
InputStream keyFileInput = new FileInputStream(keyFile);
PKCS8Key pkcs8 = new PKCS8Key(keyFileInput, p4ss.toCharArray());
KeyFactory privateKeyFactory = KeyFactory.getInstance("RSA");
PKCS8EncodedKeySpec pkcs8Encoded = new PKCS8EncodedKeySpec(pkcs8.getDecryptedBytes());
PrivateKey privateKey = privateKeyFactory.generatePrivate(pkcs8Encoded);
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initSign(privateKey);
byte[] cadenaOriginalArray = bos.toByteArray();
signature.update(cadenaOriginalArray);
String firma = new String(Base64.encodeBase64(signature.sign()), "UTF-8");
System.out.println("------------------ Cadena Original: " + bos.toString());
System.out.println("---------Firma: " + firma);

Peter comentado Ago 30

Gracias por compartir la solución! Por favor selecciona la respuesta como correcta.

Por favor, accede o regístrate para responder a esta pregunta.

¿Conoces alguien que puede responder?
¡Comparte esta pregunta!


Otras Preguntas y Respuestas


Actividad Reciente

...

Bienvenido a entre Desarrolladores, donde puedes realizar preguntas y recibir respuestas de otros miembros de la comunidad.

Conecta