Mensaje de error
TypeError: Cannot read properties of undefined (reading 'digest')
También se muestra como
- TypeError: Cannot read properties of undefined (reading 'importKey')
- TypeError: can't access property "digest", crypto.subtle is undefined
- TypeError: undefined is not an object (evaluating 'crypto.subtle.digest')
El texto es el TypeError genérico del motor: Chromium/V8, «Cannot read properties of undefined (reading 'digest')»; Firefox, «can't access property \"digest\", crypto.subtle is undefined»; Safari/WebKit, «undefined is not an object (evaluating 'crypto.subtle.digest')». El nombre del método corresponde a la primera llamada (`importKey`, `sign`, `generateKey`…).
WebCrypto — window.crypto.subtle is undefined outside a secure context (Chromium / Firefox / WebKit)
Qué significa
`crypto.subtle` no existe en esta página, así que la primera llamada sobre él falla con un TypeError genérico de «undefined». Los navegadores solo exponen `SubtleCrypto` en contextos seguros: páginas servidas por HTTPS, desde `http://localhost` / `127.0.0.1` o desde URL `file:`. El mismo código funciona en tu equipo en localhost y deja de funcionar en cuanto la página se abre por HTTP simple desde otro nombre de host o dirección IP. `crypto.getRandomValues` sigue funcionando, lo que hace que el fallo parezca selectivo.
Por qué ocurre
La página se sirve por HTTP simple
frecuenteLos hosts de preproducción, las herramientas de la intranet y los entornos de vista previa sin TLS no son contextos seguros. Ahí desaparecen todas las funciones de WebCrypto, según la especificación.
Un servidor de desarrollo abierto mediante una dirección de la LAN
frecuente`http://localhost:5173` es seguro; `http://192.168.1.20:5173` (para probar en un teléfono), no. El código que funcionaba durante el desarrollo falla en el dispositivo.
Un marco o WebView no seguro
ocasionalUna página segura incrustada en un marco padre `http:`, o un WebView que carga contenido local mediante un esquema personalizado no seguro, tampoco es un contexto seguro.
Cómo solucionarlo
- 1.
Detectarlo y fallar con un mensaje claro
Comprueba `window.isSecureContext` antes de usar WebCrypto. No recurras en silencio a un polyfill criptográfico en JavaScript: sin TLS, la integridad de la página no está garantizada de todos modos.
js if (!window.isSecureContext || !globalThis.crypto?.subtle) { throw new Error("WebCrypto needs HTTPS (or http://localhost). Current origin: " + location.origin); } const digest = await crypto.subtle.digest("SHA-256", data); - 2.
Servir la página por HTTPS
Usa TLS en todos los entornos, incluidos los servidores de desarrollo que abres desde otros dispositivos; herramientas como mkcert crean certificados de confianza local.
bash # Local HTTPS for a dev server reachable from other devices mkcert -install mkcert dev.example.test 192.168.1.20 localhost # Vite: server.https = { key: fs.readFileSync("dev.example.test+2-key.pem"), cert: fs.readFileSync("dev.example.test+2.pem") }
Errores relacionados
DataError: Data provided to an operation does not meet requirementsWebCrypto crypto.subtle.importKeyTypeError: Failed to execute 'importKey' on 'SubtleCrypto': The provided value…WebCrypto SubtleCrypto.importKeySecurityError: The relying party ID is not a registrable domain suffix of, nor…WebAuthn navigator.credentials.create() / get()