Ir al contenido

Firmas RSA

Todas las operaciones con STP se autentican mediante firmas digitales RSA-SHA256. Las claves se almacenan en AWS Secrets Manager, nunca en el código.

  • Firma (outgoing): crypto.createSign('RSA-SHA256') con clave privada en formato PEM codificada en Base64
  • Verificación (incoming): crypto.createVerify('SHA256') con clave pública de STP en Base64
  • Formato de salida: Base64

Cada tipo de operación tiene su propia clase que construye la cadena original correcta:

ClaseUso
CryptoHandlerOrdenPagoOrden de pago SPEI saliente
CryptoHandlerCuentaRegistro de cuenta en STP
CryptoHandlerAbonoVerificar abono entrante de STP
CryptoHandlerSaldoCuentaConsulta de saldo
CryptoHandlerConciliacionConsulta de conciliación
CryptoHandlerNotificacionEstadoCuentaVerificar notificación de cuenta
CryptoHandlerNotificacionEstadoTransaccionVerificar notificación de transacción

Las cadenas originales usan el separador | y siempre empiezan y terminan con ||.

||{institucionContraparte}|{empresa}|||{claveRastreo}|{institucionOperante}|{monto}|{tipoPago}|{tipoCuentaOrdenante}|{nombreOrdenante}|{cuentaOrdenante}|{rfcCurpOrdenante}|{tipoCuentaBeneficiario}|{nombreBeneficiario}|{cuentaBeneficiario}|{rfcCurpBeneficiario}||||||{conceptoPago}|||||||{referenciaNumerica}|||||||{nombreParticipanteIndirecto}|{cuentaParticipanteIndirecto}|{rfcParticipanteIndirecto}||
||{empresa}|{cuenta}|{rfcCurp}||
||{id}|{fechaOperacion}|{institucionOrdenante}|{institucionBeneficiaria}|{claveRastreo}|{monto}|{nombreOrdenante}|{tipoCuentaOrdenante}|{cuentaOrdenante}|{rfcCurpOrdenante}|{nombreBeneficiario}|{tipoCuentaBeneficiario}|{cuentaBeneficiario}|{nombreBeneficiario2}|{tipoCuentaBeneficiario2}|{cuentaBeneficiario2}|{rfcCurpBeneficiario}|{conceptoPago}|{referenciaNumerica}|{empresa}|{tipoPago}|{tsLiquidacion}|{folioCodi}||
||{empresa}|{cuentaOrdenante}|{fecha}||
||{empresa}|{tipoOrden}|{fechaOperacion}||

Notificación estado de cuenta (CryptoHandlerNotificacionEstadoCuenta)

Sección titulada «Notificación estado de cuenta (CryptoHandlerNotificacionEstadoCuenta)»
||{cuenta}|{empresa}|{estado}|{observaciones}||

Notificación estado de transacción (CryptoHandlerNotificacionEstadoTransaccion)

Sección titulada «Notificación estado de transacción (CryptoHandlerNotificacionEstadoTransaccion)»
||{id}|{empresa}|{folioOrigen}|{estado}|{causaDevolucion}|{tsLiquidacion}||
const CryptoHandler = require('./lib/cryptoHandler');
// Construir la clase con los datos de la operación
const crypto = new CryptoHandler.CryptoHandlerCuenta({
empresa: 'FINALITIX',
cuenta: '64618001000001237',
rfcCurp: 'PEGJ800101ABC'
});
// Obtener la firma en Base64
const firma = crypto.getSign(
bankSecretData.secret.passphrase,
bankSecretData.secret.privateKey // PEM en Base64
);
// Incluir en el body de la petición a STP
accountData.firma = firma;

Verificar firma entrante (incoming desde STP)

Sección titulada «Verificar firma entrante (incoming desde STP)»
// Solo se ejecuta en ENV === 'prod'
if (process.env.ENV === 'prod') {
const { firma } = body;
delete body.firma; // La firma NO se incluye en la cadena original
const crypto = new CryptoHandler.CryptoHandlerAbono(body);
const valid = crypto.verify(firma, bankSecretData.secret.publicKey); // PEM en Base64
if (!valid) {
return { status: 500, message: 'error validando firma' };
}
}

Las claves se obtienen de AWS Secrets Manager en cada sesión y se cachean en memoria:

lib/helper.js
const bankSecretData = await Helper.retrieveSecret(null, process.env.STP_SECRET_NAME);
// Estructura del secreto
{
"privateKey": "<PEM privado codificado en Base64>",
"publicKey": "<PEM público de STP codificado en Base64>",
"passphrase": "<passphrase de la clave privada>"
}