Observabilidad de aleatoriedad criptográfica y huellas del navegador
Compara Web Crypto getRandomValues con la generación aleatoria de crypto-js mediante un fixture reproducible y observaciones acotadas de privacidad.
BotBrowser Team
Quieres la documentación estructurada de Huella digital?
Este artículo forma parte de la biblioteca editorial. Para pasos de configuración, material de referencia y actualizaciones continuas, entra en la sección de docs.
BotBrowser puede repetir un fixture autorizado del mismo origen que registra disponibilidad de API y metadatos acotados de salida, pero no puede certificar la calidad de la entropía, identificar a una persona ni convertir un valor aleatorio en una huella estable. La comparación útil enfrenta el contrato de crypto.getRandomValues() controlado por el navegador con la ruta pública de crypto-js que entrega bytes aleatorios a un generador de nivel de biblioteca.
TL;DR
crypto.getRandomValues()es una API del navegador para llenar un array tipado; no expone una identidad reutilizable del navegador.crypto-jses código de aplicación. Su ruta de números aleatorios depende de la versión, el build, los globales del runtime y la rama de fuente cargada.- Compara capacidad, versión de fuente, forma del array y metadatos gruesos. Nunca publiques valores aleatorios, semillas, datos de cuenta ni muestras de entropía sin ocultar.
- Un fixture repetido puede revelar una implementación cambiada o una ruta alternativa rota, pero una salida no prueba calidad de entropía ni unicidad de huella.
Contents
- Separar las dos fuentes aleatorias
- Usar un fixture reproducible
- Diagnóstico y límites
- Leer observaciones sin exagerar
- Mantener separadas huellas y aleatoriedad
- Lectura siguiente
- Conclusión práctica
Separar las dos fuentes aleatorias
La especificación Web Cryptography define Crypto.getRandomValues() como una operación mediada por el navegador sobre un array entero tipado. La referencia de MDN documenta los tipos admitidos, el retorno síncrono y el límite de cuota. El navegador posee la fuente subyacente y puede rechazar una vista inválida; el código de página no elige una semilla.
crypto-js tiene otro modelo de propiedad. Su árbol de fuentes público contiene un helper de palabras aleatorias usado por algoritmos de la biblioteca, con comprobaciones de capacidades y un respaldo que han cambiado entre versiones. Lee la fuente etiquetada exacta que contiene tu bundle y registra si eligió un objeto crypto del navegador, otro proveedor del runtime o un respaldo. El nombre del paquete por sí solo no prueba la rama.
La comparación trata contratos observables, no la reproducción de entropía interna. Un fixture puede indicar que existe crypto.getRandomValues, que se llenó un array tipado y que un build cargado de crypto-js produjo la forma esperada. No puede convertir ninguno de los dos resultados en un identificador estable de dispositivo. Para ampliar la revisión, consulta verificación de huella del navegador e integridad de API entre realms.
Mantén los enlaces de fuente junto al fixture: fuente aleatoria de crypto-js, versiones de crypto-js y consistencia de automatización de BotBrowser. La página de docs correspondiente cubre comprobaciones de consistencia, pero no esta comparación a nivel de fuente ni sus reglas de redacción.
Usar un fixture reproducible
Ejecuta la misma página HTTPS en un perfil nuevo declarado. El fixture siguiente registra solo nombres de rama, longitudes y un digest corto de los bytes generados; nunca guarda el valor aleatorio.
async function observeRandomness() {
const record = {
fixtureId: 'crypto-randomness-01',
browserCrypto: typeof globalThis.crypto?.getRandomValues === 'function',
cryptoJsLoaded: typeof globalThis.CryptoJS !== 'undefined',
browserLength: null,
libraryLength: null,
digestPrefix: null,
outcome: 'pending',
};
try {
if (record.browserCrypto) {
const bytes = new Uint8Array(32);
globalThis.crypto.getRandomValues(bytes);
record.browserLength = bytes.byteLength;
record.digestPrefix = Array.from(bytes.slice(0, 4), value => value.toString(16).padStart(2, '0')).join('');
}
if (record.cryptoJsLoaded && typeof CryptoJS.lib.WordArray.random === 'function') {
const words = CryptoJS.lib.WordArray.random(16);
record.libraryLength = words.sigBytes;
}
record.outcome = record.browserCrypto || record.cryptoJsLoaded ? 'observed' : 'unsupported';
} catch (error) {
record.outcome = error.name === 'QuotaExceededError' ? 'quota-error' : 'api-error';
}
return record;
}
El fixture es reproducible porque sus entradas son fijas: fixtureId, un array del navegador de 32 bytes, una petición de 16 bytes de la biblioteca y la misma versión del paquete cargado. La salida no es determinista intencionalmente. Un traspaso JSON útil es:
{
"fixtureId": "crypto-randomness-01",
"browserCrypto": true,
"cryptoJsLoaded": true,
"browserLength": 32,
"libraryLength": 16,
"digestPrefix": "redacted",
"outcome": "observed"
}
Repite el fixture tras cambiar una sola variable: build del navegador, perfil, versión del paquete, bundler o runtime. Conserva browserVersion, os, profile, cryptoJsVersion y testedOn en el registro privado. No compares los bytes aleatorios; compara la primera capacidad o forma que cambie.
| Fila | Cambio único | Campos principales | Responsable |
|---|---|---|---|
| A | baseline | todos los campos del fixture | responsable de pruebas |
| B | build del navegador | browserCrypto, browserLength, outcome | navegador/contexto |
| C | ciclo de vida del perfil | capacidad y resultado | perfil |
| D | versión de crypto-js | cryptoJsLoaded, libraryLength, outcome | dependencia |
| E | salida del bundler | carga y ruta del método | build |
Diagnóstico y límites
Mantener cada solicitud de Web Crypto dentro del límite en bytes
La especificación de Web Crypto exige que getRandomValues() lance QuotaExceededError cuando el byteLength del array tipado supera 65,536. Comprueba los bytes, no el número de elementos: Uint32Array(16_384) ocupa exactamente 65,536 bytes, mientras que un elemento más supera el límite. La función siguiente acepta solo Uint8Array, donde el número de elementos también equivale a los bytes; convierte las vistas de elementos más anchos a su buffer de bytes antes de usarla:
function fillRandomBytes(output) {
if (!(output instanceof Uint8Array)) {
throw new TypeError('output must be a Uint8Array');
}
const maxBytesPerCall = 65_536;
for (let offset = 0; offset < output.byteLength; offset += maxBytesPerCall) {
const length = Math.min(maxBytesPerCall, output.byteLength - offset);
globalThis.crypto.getRandomValues(output.subarray(offset, offset + length));
}
return output;
}
Esto resuelve el límite de tamaño por llamada de la API; no hace determinista un búfer mayor, no valida la calidad de la entropía ni vuelve publicables los bytes aleatorios. Conserva la clasificación de errores del fixture: una solicitud demasiado grande es un error de forma de la petición, no evidencia de una fuente débil ni de una identidad del navegador.
Si browserCrypto es falso, revisa origen, realm y contexto antes de cambiar el perfil. Si solo cambia la biblioteca, revisa el paquete resuelto y el orden de carga. Un quota-error describe un tamaño rechazado, no entropía débil. No uses un prefijo digest como huella; conserva solo campos acotados. BotBrowser puede repetir el fixture autorizado y comparar el primer campo cambiado, pero no puede certificar calidad de entropía ni una identidad.
Leer observaciones sin exagerar
| Observación | Qué respalda | Qué no demuestra |
|---|---|---|
browserCrypto: true | la página puede llamar a la API del navegador | calidad de entropía, fuente física o identidad |
libraryLength: 16 | la biblioteca cargada devolvió la forma solicitada | qué proveedor entregó los bytes |
quota-error | el navegador rechazó el tamaño de array solicitado | perfil roto o aleatoriedad débil |
rama de cryptoJsVersion cambiada | cambio de fuente o dependencia que revisar | huella del navegador o veredicto de seguridad |
Si el campo del navegador cambia de true a false, revisa el contexto y el aislamiento de página antes de culpar al perfil. Si solo cambia el campo de la biblioteca, inspecciona el paquete resuelto y la fuente empaquetada. Si se repite un prefijo de digest, trátalo como un artefacto redactado que requiere repetir la prueba, no como una identidad estable. La recomendación Web Crypto y la fuente de crypto-js responden preguntas distintas y deben conservar citas separadas.
Mantener separadas huellas y aleatoriedad
Una huella reúne observaciones relativamente estables o controladas por política, como datos de user-agent, métricas de pantalla o disponibilidad de funciones. La salida aleatoria varía deliberadamente. Unir muestras aleatorias a un perfil puede crear un identificador de aplicación, pero ese identificador nace del modelo de datos de la aplicación, no de getRandomValues().
Para telemetría minimizada conserva id del fixture, rama de API, longitudes solicitadas, versión del paquete, resultado grueso y marca temporal. Descarta valores aleatorios, semillas, digests completos, identificadores de cuenta y uniones entre sitios. BotBrowser puede repetir el fixture autorizado y comparar esos campos acotados; no puede certificar una prueba de entropía de terceros, inferir a una persona desde una muestra ni garantizar que un respaldo de biblioteca sea adecuado para uso criptográfico.
Lectura siguiente
Consulta comportamiento determinista y validación con privacidad para separar repetición y minimización.
| Observación | Necesario para | Conservar | Descartar |
|---|---|---|---|
available or error | compatibility support | fixture id and coarse state | raw bytes and stack traces |
| requested array length | regression triage | length and browser major | complete sample values |
| seeded fixture digest | repeatability test | fixture revision and test-only digest | production account linkage |
| token reuse count | lifecycle bug | count and expiry bucket | token text and endpoint URL |
| rama de respaldo | decisión de producto | nombre de rama y revisión de app | datos de usuario usados por la página |
Conclusión práctica
Compara getRandomValues() del navegador con la fuente pública exacta de crypto-js que carga tu bundle. Usa un fixture fijo, conserva solo metadatos de capacidad y forma, y cambia una variable por repetición. El resultado puede explicar un cambio de fuente o runtime; no puede convertir aleatoriedad en huella ni probar calidad de entropía.
Public sources
Este artículo forma parte de la guía: ¿Qué es la huella digital del navegador?
Artículos Relacionados
Client Hints Fingerprinting: encabezados HTTP e identidad
Huella digitalModo determinista: huellas reproducibles del navegador
Huella digital¿Qué es la huella digital del navegador?
Huella digitalHuella de Canvas: cómo funciona y qué ayuda
Huella digitalBattery Status API: privacidad y disponibilidad
Huella digitalReproducibilidad de la semilla de ruido en ejecuciones repetibles
Lleva BotBrowser de la investigación a producción
Usa estas guías para entender el modelo y después avanzar hacia validación multiplataforma, contextos aislados y despliegue de navegador preparado para escalar.