Skip to content

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íaEn DKIMDónde vive
El anillo del reyLlave privadaSolo en el servidor que envía (Google, Zoho, tu hosting). Nunca se comparte
El dibujo del escudo que todos conocenLlave públicaEn un TXT de tu DNS, a la vista de todos
El sello en la cartaFirma DKIMUn 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=fail

Como 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 ser mitienda.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.com

Cada servicio que envía por ti tiene su propio selector, y conviven sin problema:

ServicioSelector típicoTipo de registroNombre en Cloudflare
Google Workspacegoogle (puedes cambiarlo)TXTgoogle._domainkey
Zoho MailEl que tú elijas, p. ej. zmailTXTzmail._domainkey
cPanel (Exim)defaultTXTdefault._domainkey
Microsoft 365selector1 y selector2CNAMEselector1._domainkey, selector2._domainkey
SendGrids1 y s2CNAMEs1._domainkey, s2._domainkey
Mailchimpk2 y k3CNAMEk2._domainkey, k3._domainkey
BrevoLo que indique su panel (p. ej. brevo1, brevo2)CNAME o TXTSegún el panel
Amazon SES (Easy DKIM)3 tokens aleatoriosCNAMEtoken._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 real

CNAME 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ón

Puede 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 ​

  1. Entra a la Consola de administración (admin.google.com).
  2. Ve a Aplicaciones → Google Workspace → Gmail → Autenticar correo electrónico (en inglés: Apps → Google Workspace → Gmail → Authenticate email). La ruta puede variar ligeramente.
  3. Elige el dominio mitienda.com y pulsa Generar nuevo registro.
  4. Longitud de la llave: 2048. Prefijo del selector: deja google.
  5. Google muestra:
    txt
    Nombre del host DNS:   google._domainkey
    Valor del registro TXT: v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A...IDAQAB
  6. En Cloudflare, DNS → Records → Add record:
    txt
    Type:    TXT
    Name:    google._domainkey
    Content: v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A...IDAQAB
    TTL:     Auto
  7. 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 ​

  1. Entra a la consola de administración de Zoho Mail.
  2. Ve a Dominios → mitienda.com → Configuración de correo / Autenticación de correo → DKIM (el nombre exacto puede variar).
  3. Pulsa Agregar, escribe un selector (por ejemplo zmail) y genera la llave.
  4. Zoho muestra el nombre zmail._domainkey y el valor v=DKIM1; k=rsa; p=....
  5. Crea el TXT en Cloudflare con ese nombre y valor.
  6. En Zoho pulsa Verificar y, cuando quede verificado, asegúrate de que la llave esté habilitada (marcada como predeterminada).

cPanel (correo del hosting) ​

  1. En cPanel ve a Correo electrónico → Entregabilidad de correo electrónico (Email Deliverability).
  2. Busca mitienda.com. Si los nameservers están en Cloudflare, cPanel dirá que hay "problemas", porque no puede editar tu DNS: es normal.
  3. 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...
  4. Cópialo tal cual a Cloudflare:
    txt
    Type:    TXT
    Name:    default._domainkey
    Content: v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A...
  5. 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):

  1. Entra al portal de Microsoft Defender (security.microsoft.com).
  2. 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).
  3. Selecciona mitienda.com. El portal te muestra los dos CNAME a crear. Su formato depende de tu inquilino; puede ser el nuevo:
    txt
    selector1._domainkey → selector1-mitienda-com._domainkey.mitienda.n-v1.dkim.mail.microsoft
    selector2._domainkey → selector2-mitienda-com._domainkey.mitienda.n-v1.dkim.mail.microsoft
    o el anterior, que termina en .onmicrosoft.com. Copia lo que te muestre el portal, no estos ejemplos.
  4. Créalos en Cloudflare como CNAME, con Proxy status: DNS only (nube gris).
  5. 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._domainkey y s2._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.net y k3._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.1
bash
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íntomaCausaSolució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álidaSe pegó con espacios, saltos de línea o comillas extraPega en una línea, desde el panel original
CNAME de Microsoft no se validaNube naranja (proxied)Cambia a DNS only
dkim=pass pero DMARC fallaFirma 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 correoLa lista modificó el asunto o el pieNormal; DMARC y ARC lo manejan en receptores grandes

Ejercicios ​

  1. ¿Qué nombre DNS consultarías para validar un correo con d=mitienda.com; s=zmail?
  2. 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?
  3. 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.
  4. Explica con tus palabras por qué publicar la llave pública no permite a nadie falsificar tus correos.
  5. Diseña el plan para rotar la llave de cPanel minimizando el tiempo con DKIM roto.
Ver solución
  1. zmail._domainkey.mitienda.com (TXT). Comando: nslookup -type=txt zmail._domainkey.mitienda.com 1.1.1.1 o dig +short zmail._domainkey.mitienda.com TXT.
  2. 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)
  3. 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.
  4. 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.
  5. 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._domainkey en Cloudflare (con TTL Auto = 5 min). Comprueba con dig y envía un correo de prueba a Gmail para ver dkim=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.

Academia Web — aprende, copia y construye.