Verificar Mensajes

Verificar Mensajes

Los mensajes que recibes via POST en tus webhooks vienen firmados. Para evitar ataques y fallas de seguridad debes verificar dicha firma.

Verificar Firma

Para verificar la firma, debemos realizar pasos similares a los que hicimos al generarla. El resumen es:

  1. Debes chequear la firma del JWS detached que recibes usando el certificado en la cabecera x5c del JWS junto al payload que recibiste via HTTP. Siempre debes usar el algoritmo PS256. Si el JWS especifica otro algoritmo, debes rechazarlo.

    ⚠️ El payload usado debe ser tal cual lo recibiste via HTTP.

    Si lo parseas como JSON y luego lo vuelves a llevar a un string, es posible que modifiques el payload y la firma no sea válida

  2. Debes chequar que el certificado que recibiste en el x5c era un certificado válido para tu contraparte

    ⚠️ Este paso es crítico.

    Si no comparas el certificado con un whitelist de certificado(s) que esperabas de tu(s) contraparte(s), cualquiera podría enviarte un JWS con su propio certificado en la cabecera x5c firmado con la llave privada correspondiente. ¡Todo será válido!. Es crucial entonces que valides que el certificado estaba en la lista blanca de certificados que aceptas como válidos de tu contraparte. Al cargar certificados en esa lista blanca en memoria, recomendamos también realizar los otros chequeos correspondientes: fecha de expiración, cadena de firmas, revocación, etc.

Ejemplos

En la práctica esto es bastante mecánico usando librerías existentes. Puedes ver el ejemplo mas abajo en Python como referencia.

O aún mejor, puede resultar en muy pocas líneas usando librerías/wrappers que hemos creado, como el ejemplo Python que usa python-shinkansen más abajo.

from shinkansen.responses import ResponseMessage
from shinkansen.common import SHINKANSEN, FinancialInstitution

detached_jws = ... # read Shinkansen-Jws-Signature from HTTP header
payload = ... # read from HTTP body
shinkansen_certificates = [...] # previously loaded in memory
response_message = ResponseMessage.from_json(payload)
response_message.verify(
    detached_jws, shinkansen_certificates,
    sender=SHINKANSEN,
    receiver=FinancialInstitution("MY-IDENTIFIER-AS-RECEIVER")
) # raises an exception if invalid

# We are good, we can continue reading message.header, message.responses...

Última actualización