Tema
DKIM: la firma de tus correos
SPF dice desde qué servidores puedes enviar. Pero tiene dos debilidades: se rompe cuando alguien reenvía tu correo y no protege el contenido. DKIM (DomainKeys Identified Mail) resuelve ambas cosas: cada correo sale firmado digitalmente con una llave secreta, y cualquiera puede comprobar la firma con una llave pública que publicas en tu DNS.
En esta lección entenderás la firma sin matemáticas, qué es un selector, dónde se obtiene la llave en Google Workspace, Zoho, cPanel, Microsoft 365 y plataformas de envío, y cómo rotarla.
Concepto
Analogía: el sello de lacre y el molde público
En la antigüedad, un rey sellaba sus cartas con lacre y un anillo con su escudo. Quien recibía la carta comparaba el sello con el escudo conocido del rey: si coincidía y el sello estaba intacto, la carta era auténtica y nadie la había abierto.
DKIM funciona igual, pero con matemáticas:
| En la analogía | En DKIM | Dónde vive |
|---|---|---|
| El anillo del rey | Llave privada | Solo en el servidor que envía (Google, Zoho, tu hosting). Nunca se comparte |
| El dibujo del escudo que todos conocen | Llave pública | En un TXT de tu DNS, a la vista de todos |
| El sello en la carta | Firma DKIM | Un encabezado DKIM-Signature en cada correo |
La magia de la criptografía de llave pública: lo que se firma con la privada solo se puede verificar con su pública, y con la pública no se puede fabricar una firma. Así que publicar la llave pública no tiene ningún riesgo.
Qué pasa al enviar y al recibir
txt
ENVÍO (servidor de Google Workspace)
1. Toma partes del correo: From, To, Subject, Date y el cuerpo
2. Calcula una "huella" (hash) de esas partes
3. Firma la huella con la LLAVE PRIVADA de mitienda.com
4. Agrega el encabezado:
DKIM-Signature: v=1; a=rsa-sha256; d=mitienda.com; s=google;
h=from:to:subject:date; bh=...; b=FIRMA...
RECEPCIÓN (Gmail, Outlook, Yahoo...)
5. Lee d=mitienda.com y s=google
6. Consulta el DNS: TXT google._domainkey.mitienda.com
7. Obtiene la LLAVE PÚBLICA: "v=DKIM1; k=rsa; p=MIIBIjAN..."
8. Verifica la firma y recalcula la huella
¿Coincide? → dkim=pass (el correo es auténtico y no fue alterado)
¿No? → dkim=failComo la firma viaja dentro del correo, sobrevive a los reenvíos (siempre que nadie modifique las partes firmadas). Por eso DKIM es la pieza más importante para DMARC.
Los dos datos clave: d= y s=
d=(dominio): el dominio que "firma" y se hace responsable. Para que DMARC pase con tu dominio,d=debe sermitienda.com(o un subdominio, con alineación relajada).s=(selector): el nombre de la llave. Un dominio puede tener muchas llaves a la vez (una por servicio) y el selector dice cuál usar.
Selectores: varias llaves para un mismo dominio
El receptor construye el nombre DNS así:
txt
selector ._domainkey. dominio
google ._domainkey. mitienda.com → google._domainkey.mitienda.comCada servicio que envía por ti tiene su propio selector, y conviven sin problema:
| Servicio | Selector típico | Tipo de registro | Nombre en Cloudflare |
|---|---|---|---|
| Google Workspace | google (puedes cambiarlo) | TXT | google._domainkey |
| Zoho Mail | El que tú elijas, p. ej. zmail | TXT | zmail._domainkey |
| cPanel (Exim) | default | TXT | default._domainkey |
| Microsoft 365 | selector1 y selector2 | CNAME | selector1._domainkey, selector2._domainkey |
| SendGrid | s1 y s2 | CNAME | s1._domainkey, s2._domainkey |
| Mailchimp | k2 y k3 | CNAME | k2._domainkey, k3._domainkey |
| Brevo | Lo que indique su panel (p. ej. brevo1, brevo2) | CNAME o TXT | Según el panel |
| Amazon SES (Easy DKIM) | 3 tokens aleatorios | CNAME | token._domainkey (×3) |
TXT vs CNAME: dos formas de publicar la llave
- TXT: tú pegas la llave pública en tu DNS. Si el proveedor la cambia, tienes que actualizarla tú.
- CNAME: tu DNS dice "la llave de este selector está en el DNS del proveedor". El proveedor puede rotarla sin pedirte nada. Por eso Microsoft 365, SendGrid, Mailchimp y SES usan CNAME.
txt
selector1._domainkey.mitienda.com CNAME → selector1-mitienda-com._domainkey.mitienda.n-v1.dkim.mail.microsoft
└─ ahí Microsoft publica (y rota) el TXT realCNAME de DKIM en Cloudflare: nube gris
Los CNAME de DKIM deben estar en DNS only (nube gris). Si los dejas "Proxied" (nube naranja), Cloudflare responde con sus propias IP en lugar de seguir el CNAME y la llave nunca se encuentra. Lo mismo aplica a cualquier CNAME de correo o verificación.
Anatomía del TXT de DKIM
txt
v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu5x...IDAQAB
│ │ │
│ │ └─ p= la llave pública en Base64 (si está vacía, p=, la llave fue revocada)
│ └─ k= algoritmo (rsa casi siempre; ed25519 existe pero tiene poco soporte)
└─ versiónPuede llevar más etiquetas, como t=s (estricto con subdominios) o t=y (modo prueba). No las agregues por tu cuenta: copia exactamente lo que te dé el proveedor.
1024 vs 2048 bits
Usa 2048 bits siempre que el proveedor lo permita. Las llaves de 1024 bits todavía se aceptan (Gmail y Yahoo piden mínimo 1024), pero 2048 es el estándar actual. Una llave de 2048 bits mide unos 400 caracteres, más que el límite de 255 de una cadena TXT: pégala completa en una línea y Cloudflare la divide sola (lo viste en la lección de TXT).
Paso a paso por proveedor
En todos los casos el patrón es: 1) el proveedor genera la llave → 2) tú publicas el registro en Cloudflare → 3) vuelves al proveedor y activas la firma. Si activas antes de publicar, los correos salen con una firma que nadie puede verificar.
Google Workspace
- Entra a la Consola de administración (admin.google.com).
- Ve a Aplicaciones → Google Workspace → Gmail → Autenticar correo electrónico (en inglés: Apps → Google Workspace → Gmail → Authenticate email). La ruta puede variar ligeramente.
- Elige el dominio
mitienda.comy pulsa Generar nuevo registro. - Longitud de la llave: 2048. Prefijo del selector: deja
google. - Google muestra:txt
Nombre del host DNS: google._domainkey Valor del registro TXT: v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A...IDAQAB - En Cloudflare, DNS → Records → Add record:txt
Type: TXT Name: google._domainkey Content: v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A...IDAQAB TTL: Auto - Espera unos minutos, vuelve a la consola de Google y pulsa Iniciar autenticación. El estado debe cambiar a "Autenticando correo electrónico con DKIM".
Si Google dice que no encuentra el registro
Puede tardar hasta 48 horas en reconocerlo según su documentación, aunque con Cloudflare suele ser cuestión de minutos. Comprueba primero con nslookup -type=txt google._domainkey.mitienda.com 1.1.1.1. Si aparece, solo es esperar.
Zoho Mail
- Entra a la consola de administración de Zoho Mail.
- Ve a Dominios → mitienda.com → Configuración de correo / Autenticación de correo → DKIM (el nombre exacto puede variar).
- Pulsa Agregar, escribe un selector (por ejemplo
zmail) y genera la llave. - Zoho muestra el nombre
zmail._domainkeyy el valorv=DKIM1; k=rsa; p=.... - Crea el TXT en Cloudflare con ese nombre y valor.
- En Zoho pulsa Verificar y, cuando quede verificado, asegúrate de que la llave esté habilitada (marcada como predeterminada).
cPanel (correo del hosting)
- En cPanel ve a Correo electrónico → Entregabilidad de correo electrónico (Email Deliverability).
- Busca
mitienda.com. Si los nameservers están en Cloudflare, cPanel dirá que hay "problemas", porque no puede editar tu DNS: es normal. - Pulsa Administrar (Manage). En la sección DKIM verás el registro sugerido:txt
Name: default._domainkey.mitienda.com. Value: v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A... - Cópialo tal cual a Cloudflare:txt
Type: TXT Name: default._domainkey Content: v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A... - Recarga Email Deliverability: el estado de DKIM debe aparecer como válido. Aprovecha y copia también el SPF que sugiere (compáralo con el tuyo, no crees un segundo SPF).
Microsoft 365
Microsoft usa dos CNAME (dos selectores, para rotar sin cortes):
- Entra al portal de Microsoft Defender (security.microsoft.com).
- Ve a Correo electrónico y colaboración → Directivas y reglas → Directivas de amenazas → Configuración de autenticación de correo electrónico → DKIM (la ruta cambia con frecuencia; también puedes buscar "DKIM" en el portal).
- Selecciona
mitienda.com. El portal te muestra los dos CNAME a crear. Su formato depende de tu inquilino; puede ser el nuevo:txto el anterior, que termina enselector1._domainkey → selector1-mitienda-com._domainkey.mitienda.n-v1.dkim.mail.microsoft selector2._domainkey → selector2-mitienda-com._domainkey.mitienda.n-v1.dkim.mail.microsoft.onmicrosoft.com. Copia lo que te muestre el portal, no estos ejemplos. - Créalos en Cloudflare como CNAME, con Proxy status: DNS only (nube gris).
- Vuelve al portal y activa Firmar mensajes para este dominio con firmas DKIM.
SendGrid, Mailchimp y similares
- SendGrid: Settings → Sender Authentication → Authenticate Your Domain. Te da 3 CNAME:
em1234(Return-Path),s1._domainkeyys2._domainkey. Créalos en nube gris y pulsa Verify. - Mailchimp: Configuración de la cuenta → Dominios → Autenticar. Te da CNAME como
k2._domainkey → dkim2.mcsv.netyk3._domainkey → dkim3.mcsv.net. - Amazon SES: al verificar una identidad de dominio con Easy DKIM, te da 3 CNAME
token._domainkey → token.dkim.amazonses.com.
Comprobar DKIM
Para consultar la llave necesitas saber el selector. No hay forma estándar de listar todos los selectores de un dominio.
powershell
nslookup -type=txt google._domainkey.mitienda.com 1.1.1.1
nslookup -type=txt default._domainkey.mitienda.com 1.1.1.1
# Para un selector con CNAME (Microsoft 365, SendGrid)
nslookup -type=cname selector1._domainkey.mitienda.com 1.1.1.1bash
dig +short google._domainkey.mitienda.com TXT
dig +short default._domainkey.mitienda.com TXT
# CNAME: dig sigue la cadena y muestra el destino y el TXT final
dig selector1._domainkey.mitienda.com TXT¿Cómo averiguas el selector de un correo que ya recibiste? En Gmail: ⋮ → Mostrar original y busca el encabezado DKIM-Signature:
txt
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=mitienda.com; s=google;
h=mime-version:from:date:message-id:subject:to;
bh=47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=;
b=Hk3Ls...d=mitienda.com y s=google → la llave está en google._domainkey.mitienda.com. Y en Authentication-Results:
txt
dkim=pass header.i=@mitienda.com header.s=google header.b=Hk3Ls...Si ves header.i=@gappssmtp.com o d= de otro dominio, el correo está firmado, pero no con tu dominio: no ayuda a DMARC. Pasa con Workspace cuando no activaste DKIM propio.
Rotación de llaves
Una llave privada que se usa durante años es un riesgo: si se filtra, alguien puede firmar como tú. Rotar significa cambiar la llave cada cierto tiempo (por ejemplo, cada 6–12 meses, o de inmediato si sospechas una filtración).
Rotación sin cortes (con dos selectores)
txt
Día 0 Publicas la llave NUEVA con un selector nuevo google2._domainkey (TXT)
La vieja sigue publicada y en uso google._domainkey (TXT)
Día 1 Activas la firma con google2 en el proveedor
Los correos nuevos salen con s=google2
Día 7+ Dejas la vieja publicada una o dos semanas
(hay correos en tránsito o en colas que aún la usan)
Día 14 Borras google._domainkey (o lo dejas con p= vacío para "revocarla")- En Microsoft 365 y en servicios con CNAME, la rotación la hace el proveedor: tú no tocas el DNS.
- En Google Workspace puedes generar un registro nuevo con otro prefijo de selector y seguir los mismos pasos.
- En cPanel, regenerar la llave cambia el valor de
default._domainkey: actualiza el TXT de Cloudflare justo después, porque hasta que lo hagas DKIM fallará.
Errores comunes
| Síntoma | Causa | Solución |
|---|---|---|
dkim=fail (no key for signature) | No existe el TXT del selector, o el nombre está mal (google._domainkey.mitienda.com.mitienda.com) | Revisa el nombre exacto con dig |
dkim=fail (bad signature) | La llave publicada no coincide con la privada (regeneraste la llave y no actualizaste el DNS) | Copia de nuevo la llave actual del proveedor |
dkim=permerror / llave inválida | Se pegó con espacios, saltos de línea o comillas extra | Pega en una línea, desde el panel original |
| CNAME de Microsoft no se valida | Nube naranja (proxied) | Cambia a DNS only |
dkim=pass pero DMARC falla | Firma con d= de otro dominio (el del proveedor) | Activa DKIM con tu propio dominio en el proveedor |
| Pasa al enviar, falla al reenviar por una lista de correo | La lista modificó el asunto o el pie | Normal; DMARC y ARC lo manejan en receptores grandes |
Ejercicios
- ¿Qué nombre DNS consultarías para validar un correo con
d=mitienda.com; s=zmail? - Tu cliente usa Google Workspace para el correo y el hosting cPanel para los formularios. ¿Cuántos registros DKIM necesita, de qué tipo y con qué nombres?
- Creaste los CNAME de DKIM de Microsoft 365 hace una hora y el portal sigue diciendo que no existen. Escribe dos cosas que revisarías.
- Explica con tus palabras por qué publicar la llave pública no permite a nadie falsificar tus correos.
- Diseña el plan para rotar la llave de cPanel minimizando el tiempo con DKIM roto.
Ver solución
zmail._domainkey.mitienda.com(TXT). Comando:nslookup -type=txt zmail._domainkey.mitienda.com 1.1.1.1odig +short zmail._domainkey.mitienda.com TXT.- Dos registros TXT (uno por servicio, cada uno con su selector):txt
TXT google._domainkey v=DKIM1; k=rsa; p=...(llave de Google) TXT default._domainkey v=DKIM1; k=rsa; p=...(llave de cPanel) - a) Que estén en DNS only (nube gris) y no proxied. b) Que el nombre y el destino sean exactamente los del portal (sin el dominio duplicado y sin espacios). Comprueba con
nslookup -type=cname selector1._domainkey.mitienda.com 1.1.1.1. - La llave pública solo sirve para verificar firmas. Para crear una firma válida se necesita la llave privada, que nunca sale del servidor que envía. Con la pública es matemáticamente impráctico calcular la privada.
- Ten Cloudflare abierto en una pestaña y cPanel en otra. Regenera la llave en Email Deliverability, copia el nuevo valor y edita de inmediato el TXT
default._domainkeyen Cloudflare (con TTL Auto = 5 min). Comprueba condigy envía un correo de prueba a Gmail para verdkim=pass. Hazlo en un horario de poco envío.
Resumen
- DKIM firma cada correo con una llave privada; los receptores verifican con la llave pública publicada en tu DNS.
- La llave está en
selector._domainkey.tudominio. El selector (s=) permite tener varias llaves:google,default,selector1,s1… - Algunos proveedores usan TXT (Workspace, Zoho, cPanel) y otros CNAME (Microsoft 365, SendGrid, Mailchimp, SES). Los CNAME siempre en nube gris.
- Orden correcto: generar llave → publicar en DNS → activar firma.
- Para DMARC importa que
d=sea tu dominio. - Usa 2048 bits y rota las llaves con un selector nuevo, dejando la vieja unos días.
- Siguiente: DMARC: la política que une todo.