thegreenter / xmldsig

Firma digital en Facturación Electrónica
BSD 3-Clause "New" or "Revised" License
37 stars 14 forks source link

Indicar passphrase para certificado con clave privada #5

Closed Gonsabb closed 5 years ago

Gonsabb commented 5 years ago

Hola, estoy intentando firmar un xml con un certificado pem que tiene una clave privada, hasta donde he podido ver en la clase XMLSecurityKey se declara una variable publica como: $passphrase = "";

Después de buscar un rato no he encontrado ningún setter para esta variable, la cosa es que necesito indicar el passphrase para poder firmar el documento ya que si no la función openssl_get_privatekey( ) (ubicada en la línea 345 del archivo XMLSecurityKey.php) me devuelve un false al pasarse la variable $this->passphrase.

Toda ayuda es bienvenida. Gracias!

giansalex commented 5 years ago

Hola @Gonsabb, y que error te sale al realizar el ejemplo, ya que recibe un .pem

Gonsabb commented 5 years ago

Hola @giansalex gracias por la respuesta tan rápida. En el ejemplo no me da ningún error.

Estoy pasando un certificado .pem y la ejecución se corta al llamar a la función openssl_sign().

Te indico el error que me devuelve la función openssl_error_string() al llamarla justo despues de la línea 345: $this->key = openssl_pkey_get_private($this->key, $this->passphrase);

Error: error:0907B068:PEM routines:PEM_READ_BIO_PRIVATEKEY:bad password read

Basicamente viene porque al evaluar el tipo de clave entra por la privada pero al estar el passphrase vacío no puede obtener la clave, por lo que retorna un false y lo va arrastrando hasta que intenta firmar el documento sin tener la key.

El certificado pem que estoy pasando tiene una clave privada, si indico manualmente el passphrase en esa línea de código el documento queda firmado correctamente.

giansalex commented 5 years ago

Tal vez tiene que ver al momento de exportar, aqui hay un ejemplo para exportar un certificado pfx a .pem el cual incluye la clave publica y privada.

Gonsabb commented 5 years ago

Puede ser por eso si, la cosa es que el certificado desde el que tengo que transformar a .pem es un .p12 y no un .pfx, también he usado openssl para generarlo a través de comandos. Voy a probar a transformarlo de nuevo e intentar generarlo con clave pública y privada, entiendo que en el momento en el que la clave sea pública todo funcionará perfectamente.

Sin embargo el problema original sigue persistiendo: si el certificado .pem solo tiene clave privada la librería falla.

Te pongo un ejemplo del contenido del tipo de certificado con el que estoy trabajando:

Bag Attributes friendlyName: ... localKeyID: .... Key Attributes: -----BEGIN PRIVATE KEY----- ................................................. -----END PRIVATE KEY----- Bag Attributes friendlyName: .... localKeyID: .... subject=/description=.... -----BEGIN CERTIFICATE----- .................................................. -----END CERTIFICATE-----

giansalex commented 5 years ago

Trata de convertirlo a .pfx luego este a .pem, pero el .pem debe incluir tanto la clave publica como privada, ambas son necesarias

Gonsabb commented 5 years ago

He estado parte de la mañana intentando sacar la clave pública a partir de la privada pero no he llegado a dar con la tecla, al final he realizado unas modificaciones en la librería que me han permitido firmar el documento pasando el passphrase de la clave privada del certificado con certificados que solo tienen clave privada.

Gracias por la ayuda de todos modos!

giansalex commented 5 years ago

Y como resulta el XML? Ya que debe incluir la clave pública en su interior

giansalex commented 5 years ago

Puedes utilizar esta herramienta que dispone un proveedor de certificados. https://llama.pe/cambiar-extension-p12-a-pfx

Gonsabb commented 5 years ago

El xml me aparece firmado, sin embargo voy a validarlo a ver si me encuentra algún error, te mantengo informado si me funciona.

giansalex commented 5 years ago

Si, pero aparte es necesario que incluya la clave publica en el xml, para poder verificar su autenticidad. Te recomendaria que lo conviertas a .pfx en la url que te pase, y luego obtengas el .pem

Gonsabb commented 5 years ago

Ok, pues voy a probarlo porque en la validación me ha dado un error, en cuanto lo haya testeado todo de nuevo te confirmo. Gracias por la ayuda!

Gonsabb commented 5 years ago

Hola @giansalex he realizado el traspaso de p12 a pfx y luego he usado la librería para transformar el pfx a pem indicando la clave del certificado, sin embargo el certificado pem resultante me viene solo con la clave privada. Entiendo que se debe a que el certificado original solo viene con la clave privada. ¿Existe alguna forma de generar la clave pública a partir de la privada? Ayer me pase medio día investigando y no conseguí dar con nada en la web...

Edito: al final he conseguido incluir la clave publica generada a partir de la privada, sin embargo para completar la firma del documento me hace falta añadir mas etiquetas e información al documento.

PD: el documento xsig generado ha quedado correctamente firmado usando la librería.

Muchas gracias por la ayuda!

giansalex commented 5 years ago

Ambas claves te debieron ser proporcionadas por el proveedor de certificado, sino deberías consultar con ellos, ya que la clave publica (.cer) es la que se sube al portal de SUNAT.