npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@cfdi/csd

v4.0.18

Published

Certificados de Sello Digital (CSD) - lectura de archivos .cer y .key para CFDI

Readme


Ecosistema CFDI


Instalacion

npm install @cfdi/csd

API

@cfdi/csd lee y opera certificados X.509 (.cer) y llaves privadas RSA (.key) del SAT mexicano. Cubre CSD (Certificado de Sello Digital) y FIEL (e.firma).

Clases

| Clase | Responsabilidad | |---|---| | Certificate | Wrapper del .cer X.509 (CSD o FIEL) | | PrivateKey | Wrapper del .key RSA (PKCS#8 cifrado, PKCS#8 plano o PKCS#1) | | Credential | Une Certificate + PrivateKey para firmar/verificar | | Ocsp | Validación de revocación contra el responder OCSP del SAT |

Certificate

import { Certificate } from '@cfdi/csd';

const cert = await Certificate.fromFile('mi.cer');         // DER o PEM auto
// también: Certificate.fromDer(buf), Certificate.fromPem(str), fromFileSync

Identidad / metadata

| Método | Retorna | Descripción | |---|---|---| | serialNumber() | string (hex) | Serial del cert | | noCertificado() | string (20 dig) | Número de certificado SAT | | rfc() | string | RFC del titular (subject OID 2.5.4.45 / 2.5.4.5 / UID) | | legalName() | string | Razón social / nombre del CN | | subject() | Record<string, string> | Subject como mapa atributo→valor | | issuer() | Record<string, string> | Issuer como mapa atributo→valor | | validFrom() | Date | Inicio de vigencia | | validTo() | Date | Fin de vigencia | | isExpired() | boolean | now > validTo | | isValid() | boolean | validFrom ≤ now ≤ validTo (vigente) | | acVersion() | number \| null | Versión de AC del SAT (4 o 5) — desde dígito 12 del noCertificado | | subjectType() | 'MORAL' \| 'FISICA' \| 'UNKNOWN' | Persona moral o física, derivado del OID 2.5.4.45 |

Tipo de certificado

| Método | Retorna | |---|---| | certificateType() | 'CSD' \| 'FIEL' \| 'UNKNOWN' — por extensiones X.509 (extKeyUsage / keyUsage), fallback a OU | | isCsd() | boolean — equivalente a certificateType() === 'CSD' | | isFiel() | boolean — equivalente a certificateType() === 'FIEL' |

"FIEL" y "e.firma" son la misma cosa: nomenclatura legal vs marca comercial del SAT.

Conversiones / hashing

| Método | Retorna | |---|---| | toPem() | string PEM con cabeceras | | toDer() | Buffer DER | | toBase64() | string base64 sin cabeceras ni saltos | | publicKey() | string PEM -----BEGIN PUBLIC KEY----- | | fingerprint() | string SHA-1 con : (AA:BB:...) | | fingerprintSha256() | string SHA-256 hex |

Verificación

| Método | Retorna | |---|---| | verify(data, signatureBase64, alg='SHA256') | boolean — verifica firma contra data con la pública del cert | | verifyIssuedBy(issuer) | booleantrue si fue firmado por issuer (cadena AC) | | verifyIntegrity(issuer) | alias de verifyIssuedBy (compat con e.firma) | | rsaEncrypt(message) | string base64 — encripta con la pública del cert |

PrivateKey

import { PrivateKey } from '@cfdi/csd';

// .key del SAT (PKCS#8 cifrado)
const key = await PrivateKey.fromFile('mi.key', '12345678a');

// strict: solo acepta PKCS#8 cifrado
const sat = await PrivateKey.fromFile('mi.key', '12345678a', { strict: true });

| Método | Retorna | |---|---| | fromDer(buf, password, opts?) | acepta PKCS#8 cifrado, PKCS#8 plano o PKCS#1 | | fromPem(pem) | PEM sin cifrado | | fromFile(path, password, opts?) | DER o PEM auto | | fromFileSync(path, password, opts?) | versión síncrona | | toPem() | PEM PKCS#8 sin cifrar | | sign(data, alg='SHA256') | firma base64 | | rsaDecrypt(encryptedBase64) | desencripta lo que Certificate.rsaEncrypt produjo | | belongsToCertificate(cert) | true si la pública de la llave == pública del cert |

Credential

import { Credential } from '@cfdi/csd';

const cred = await Credential.create('mi.cer', 'mi.key', '12345678a');
const sello = cred.sign('||cadena|original||');
cred.verify('||cadena|original||', sello); // true

| Método | Retorna | |---|---| | create(cerPath, keyPath, password) | desde rutas | | fromPem(cerPem, keyPem) | desde PEM strings | | sign(data, alg='SHA256') | firma base64 | | verify(data, sig, alg='SHA256') | bool | | rfc(), legalName(), noCertificado(), serialNumber() | proxy al cert | | isCsd(), isFiel(), isValid(), belongsTo(rfc) | predicados | | keyMatchesCertificate() | bool |

Ocsp — validación de revocación SAT

El SAT expone https://cfdi.sat.gob.mx/edofiel para consultar el estado (GOOD / REVOKED) de un certificado en línea. Se necesitan tres certificados:

import { Ocsp, Certificate } from '@cfdi/csd';

const subject = await Certificate.fromFile('contribuyente.cer');
const issuer = await Certificate.fromFile('AC5_SAT.cer');
const ocspCert = await Certificate.fromFile('ocsp.ac5_sat.cer');

const ocsp = new Ocsp('https://cfdi.sat.gob.mx/edofiel', issuer, subject, ocspCert);
const res = await ocsp.verify();

if (res.status === 'REVOKED') {
  console.log('Certificado revocado el', res.revocationTime);
}

| Método | Retorna | |---|---| | verify() | { status, revocationTime?, ocspRequestBase64, ocspResponseBase64 } | | parseResponseStatus(asn1) | OcspResponseStatus | | parseCertificateStatus(asn1Basic) | { status, revocationTime? } | | verifyResponseSignature(asn1Basic) | boolean |


Compatibilidad con el paquete e.firma

Si vienes del paquete e.firma:

| e.firma | @cfdi/csd | |---|---| | new x509Certificate(bin) | await Certificate.fromFile(path) o Certificate.fromDer(buf) | | cert.certificateType ('CSD' \| 'EFIRMA') | cert.certificateType() ('CSD' \| 'FIEL') | | cert.acVersion | cert.acVersion() | | cert.subjectType | cert.subjectType() | | cert.valid | cert.isValid() | | cert.serialNumber | cert.serialNumber() | | cert.getPEM() | cert.toPem() | | cert.getBinary() | cert.toDer() | | cert.verifyIntegrity(issuerBin) | cert.verifyIssuedBy(issuer) (alias verifyIntegrity disponible) | | cert.rsaEncrypt(msg) | cert.rsaEncrypt(msg) | | cert.rsaVerifySignature(msg, sig) | cert.verify(msg, sig) | | new PrivateKey(bin) (cifrada solamente) | await PrivateKey.fromFile(path, pwd, { strict: true }) | | key.rsaDecrypt(text, pwd) | key.rsaDecrypt(text) (la pwd va en el from*) | | key.rsaSign(msg, pwd) | key.sign(msg) | | new Ocsp(url, issuer, subject, ocsp) | new Ocsp(url, issuer, subject, ocsp) |


Soporte


Autor

Licencia

MIT