Library to use eFirma (fiel) and CSD (sellos) from SAT
🇺🇸 The documentation of this project is in spanish as this is the natural language for intented audience.
🇲🇽 La documentación del proyecto está en español porque ese es el lenguaje principal de los usuarios.
Esta librería ha sido creada para poder trabajar con los archivos CSD y FIEL del SAT. De esta forma, se simplifica el proceso de firmar, verificar firma y obtener datos particulares del archivo de certificado así como de la llave pública.
-
El CSD (Certificado de Sello Digital) es utilizado para firmar Comprobantes Fiscales Digitales.
-
La FIEL (o eFirma) es utilizada para firmar electrónicamente documentos (generalmente usando XML-SEC) y está reconocida por el gobierno mexicano como una manera de firma legal de una persona física o moral.
Con esta librería no es necesario convertir los archivos generados por el SAT a otro formato, se pueden utilizar tal y como el SAT los entrega.
Usa composer
composer require phpcfdi/credentials
<?php declare(strict_types=1);
$cerFile = 'fiel/certificado.cer';
$pemKeyFile = 'fiel/privatekey.key';
$passPhrase = '12345678a'; // contraseña para abrir la llave privada
$fiel = PhpCfdi\Credentials\Credential::openFiles($cerFile, $pemKeyFile, $passPhrase);
$sourceString = 'texto a firmar';
// alias de privateKey/sign/verify
$signature = $fiel->sign($sourceString);
echo base64_encode($signature), PHP_EOL;
// alias de certificado/publicKey/verify
$verify = $fiel->verify($sourceString, $signature);
var_dump($verify); // bool(true)
// objeto certificado
$certificado = $fiel->certificate();
echo $certificado->rfc(), PHP_EOL; // el RFC del certificado
echo $certificado->legalName(), PHP_EOL; // el nombre del propietario del certificado
echo $certificado->branchName(), PHP_EOL; // el nombre de la sucursal (en CSD, en FIEL está vacía)
echo $certificado->serialNumber()->bytes(), PHP_EOL; // número de serie del certificado
Los archivos de certificado vienen en formato X.509 DER
y los de llave privada en formato PKCS#8 DER
.
Ambos formatos no se pueden interpretar directamente en PHP (con ext-openssl
), sin embargo sí lo pueden hacer
en el formatos compatible PEM
.
Esta librería tiene la capacidad de hacer esta conversión internamente (sin openssl
), pues solo consiste en codificar
a base64
, en renglones de 64 caracteres y con cabeceras específicas para certificado y llave privada.
De esta forma, para usar el certificado AAA010101AAA.cer
o la llave privada AAA010101AAA.key
provistos por
el SAT, no es necesario convertirlos con openssl
y la librería los detectará correctamente.
El objeto Certificate
no se creará si contiene datos no válidos.
El SAT entrega el certificado en formato X.509 DER
, por lo que internamente se puede convertir a X.509 PEM
.
También es frecuente usar el formato X.509 DER base64
, por ejemplo, en el atributo Comprobante@Certificado
o en las firmas XML, por este motivo, los formatos soportados para crear un objeto Certificate
son
X.509 DER
, X.509 DER base64
y X.509 PEM
.
- Para abrir usando un archivo local:
$certificate = Certificate::openFile($filename);
- Para abrir usando una cadena de caracteres:
$certificate = new Certificate($content);
- Si
$content
es un certificado en formatoX.509 PEM
con cabeceras ese se utiliza. - Si
$content
está totalmente enbase64
, se interpreta comoX.509 DER base64
y se formatea aX.509 PEM
- En otro caso, se interpreta como formato
X.509 DER
, por lo que se formatea aX.509 PEM
.
- Si
El objeto PrivateKey
no se creará si contiene datos no válidos.
En SAT entrega la llave en formato PKCS#8 DER
, por lo que internamente se puede convertir a PKCS#8 PEM
(con la misma contraseña) y usarla desde PHP.
Una vez abierta la llave también se puede cambiar o eliminar la contraseña, creando así un nuevo objeto PrivateKey
.
- Para abrir usando un archivo local:
$key = PrivateKey::openFile($filename, $passPhrase);
- Para abrir usando una cadena de caracteres:
$key = new PrivateKey($content, $passPhrase);
- Si
$content
es una llave privada en formatoPEM
(PKCS#8
oPKCS#5
) se utiliza. - En otro caso, se interpreta como formato
PKCS#8 DER
, por lo que se formatea aPKCS#8 PEM
.
- Si
Notas de tratamiento de archivos DER
:
- Al convertir
PKCS#8 DER
aPKCS#8 PEM
se determina si es una llave encriptada si se estableció una contraseña, si no se estableció se tratará como una llave plana (no encriptada). - No se sabe reconocer de forma automática si se trata de un archivo
PKCS#5 DER
por lo que este tipo de llave se deben convertir manualmente antes de intentar abrirlos, su cabecera esRSA PRIVATE KEY
. - A diferencia de los certificados que pueden interpretar un formato
DER base64
, la lectura de llave privada no hace esta distinción, si desea trabajar con un formato sin caracteres especiales usePEM
.
Para entender más de los formatos de llaves privadas se puede consultar la siguiente liga: https://github.com/kjur/jsrsasign/wiki/Tutorial-for-PKCS5-and-PKCS8-PEM-private-key-formats-differences
Esta librería se mantendrá compatible con al menos la versión con soporte activo de PHP más reciente.
También utilizamos Versionado Semántico 2.0.0 por lo que puedes usar esta librería sin temor a romper tu aplicación.
Las contribuciones con bienvenidas. Por favor lee CONTRIBUTING para más detalles y recuerda revisar el archivo de tareas pendientes TODO y el CHANGELOG.
The phpcfdi/finkok library is copyright © PhpCfdi and licensed for use under the MIT License (MIT). Please see LICENSE for more information.