Logotipo de Zephyrnet

Passkeys: ¿Qué diablos y por qué?

Fecha:

Estas cosas llamadas llaves maestras seguro que están haciendo las rondas en estos días. Eran una atracción principal en W3C TPAC 2022, ganó apoyo en Safari 16, están encontrando su camino en macOS y iOS, y están programados para ser el futuro de los administradores de contraseñas como 1Password. Ellos son ya soportado en Android, y pronto llegará a Chrome OS y Windows en versiones futuras.

Las mejoras de seguridad de Geeky OS no son precisamente los grandes titulares en la comunidad front-end, pero es lógico pensar que las claves de acceso van a ser una "cosa". Y teniendo en cuenta cómo las contraseñas y las aplicaciones de contraseñas afectan la experiencia del usuario en cosas como la autenticación y el procesamiento de formularios, es posible que queramos al menos entenderlas, para saber lo que viene.

Ese es el punto de este artículo. He estado estudiando y experimentando con claves de acceso, y la API de WebAuthn sobre la que están construidas, desde hace algún tiempo. Déjame compartir lo que he aprendido.

Tabla de contenidos.

Terminología

Aquí está la sección obligatoria de la terminología que querrá saber a medida que profundizamos. Como la mayoría de la tecnología, las claves de acceso están forjadas con palabrería esotérica y acrónimos que a menudo son obstáculos para la comprensión. Intentaré desmitificar varios para usted aquí.

  • Fiesta de confianza: el servidor contra el que se autenticará. Usaremos "servidor" para implicar a la parte que confía en este artículo.
  • Cliente: en nuestro caso, el navegador web o el sistema operativo.
  • Autenticador: Dispositivos de software y/o hardware que permiten generar y almacenar pares de claves públicas.
  • FIDO: un organismo de estándares abiertos que también crea especificaciones en torno a las credenciales FIDO.
  • WebAuthn: El protocolo subyacente para claves de acceso, también conocido como FIDO2 credencial o credenciales FIDO de un solo dispositivo.
  • Claves de paso: WebAuthn, pero con sincronización en la nube (también denominadas credenciales FIDO multidispositivo, credenciales detectables o credenciales residentes).
  • Criptografía de clave pública: Un par de claves generado que incluye una clave pública y una privada. Según el algoritmo, debe usarse para firmar y verificar o cifrar y descifrar. Esto también se conoce como criptografía asimétrica.
  • RSA: Un acrónimo de los nombres de los creadores, Rivest Shamir y Adel. RSA es una familia de criptografía de clave pública más antigua, pero aún útil, basada en la factorización de números primos.
  • Criptografía de curva elíptica (ECC): Una nueva familia de criptografía basado en curvas elípticas.
  • ES256: Una clave pública de curva elíptica que utiliza un algoritmo de firma ECDSA ((PDF)) con SHA256 para hash.
  • RS256: Como ES256, pero usa RSA con RSASSA-PKCS1-v1.5 y SHA256.

¿Qué son las claves de paso?

Antes de que podamos hablar específicamente sobre claves de paso, debemos hablar sobre otro protocolo llamado WebAuthn (también conocido como FIDO2). Las claves de acceso son una especificación que se basa en WebAuthn. WebAuthn permite que la criptografía de clave pública reemplace las contraseñas. Utilizamos algún tipo de dispositivo de seguridad, como una llave de hardware o Trusted Platform Module (TPM), para crear claves públicas y privadas.

La clave pública es para que cualquiera la use. Sin embargo, la clave privada no se puede eliminar del dispositivo que la generó. Este fue uno de los problemas con WebAuthn; si pierde el dispositivo, pierde el acceso.

Passkeys resuelve esto proporcionando una sincronización en la nube de sus credenciales. En otras palabras, lo que genera en su computadora ahora también se puede usar en su teléfono (aunque, de manera confusa, también hay credenciales de un solo dispositivo).

Actualmente, al momento de escribir este artículo, solo iOS, macOS y Android brindan soporte completo para las claves de acceso sincronizadas en la nube, e incluso entonces, están limitadas por el navegador que se utiliza. Google y Apple proporcionan una interfaz para sincronizar a través de sus Administrador de contraseñas de GoogleLlavero Apple iCloud servicios, respectivamente.

¿Cómo reemplazan las claves de paso las contraseñas?

En la criptografía de clave pública, puede realizar lo que se conoce como firma. La firma toma un dato y luego lo ejecuta a través de un algoritmo de firma con la clave privada, donde luego se puede verificar con la clave pública.

Cualquiera puede generar un par de claves públicas y no es atribuible a ninguna persona, ya que cualquier persona podría haberlo generado en primer lugar. Lo que lo hace útil es que solo los datos firmados con la clave privada pueden verificarse con la clave pública. Esa es la parte que reemplaza una contraseña: un servidor almacena la clave pública e iniciamos sesión verificando que tenemos la otra mitad (por ejemplo, clave privada), firmando un desafío aleatorio.

Como beneficio adicional, dado que almacenamos las claves públicas del usuario dentro de una base de datos, ya no hay preocupación por las violaciones de contraseña que afectan a millones de usuarios. Esto reduce el phishing, las infracciones y una serie de otros problemas de seguridad a los que se enfrenta actualmente nuestro mundo dependiente de contraseñas. Si se viola una base de datos, todo eso se almacena en las claves públicas del usuario, lo que lo hace prácticamente inútil para un atacante.

¡Tampoco más correos electrónicos olvidados y sus contraseñas asociadas! El navegador recordará qué credenciales usó para qué sitio web: todo lo que necesita hacer es hacer un par de clics e iniciar sesión. Puede proporcionar un medio secundario de verificación para usar la clave de acceso, como datos biométricos o un pin. , pero siguen siendo mucho más rápidas que las contraseñas de antaño.

Más sobre criptografía

La criptografía de clave pública implica tener una clave privada y una pública (conocida como un par de claves). Las claves se generan juntas y tienen usos separados. Por ejemplo, la clave privada está destinada a mantenerse en secreto y la clave pública está destinada a cualquier persona con la que desee intercambiar mensajes.

Cuando se trata de cifrar y descifrar un mensaje, la clave pública del destinatario se usa para cifrar un mensaje para que solo la clave privada del destinatario pueda descifrar el mensaje. En la jerga de la seguridad, esto se conoce como "brindar confidencialidad". Sin embargo, esto no proporciona prueba de que el remitente es quien dice ser, ya que cualquiera puede potencialmente usar una clave pública para enviarle a alguien un mensaje encriptado.

Hay casos en los que necesitamos verificar que un mensaje efectivamente vino de su remitente. En estos casos, usamos firma y verificación de firma para asegurarnos de que el remitente es quien dice ser (también conocido como autenticidad). En clave pública (también llamada asimétrico) criptografía, esto generalmente se hace firmando el hash de un mensaje, para que solo la clave pública pueda verificarlo correctamente. El hash y la clave privada del remitente producen una firma después de ejecutarla a través de un algoritmo, y luego cualquiera puede verificar que el mensaje proviene del remitente con la clave pública del remitente.

¿Cómo accedemos a las claves de acceso?

Para acceder a las claves de acceso, primero debemos generarlas y almacenarlas en algún lugar. Parte de esta funcionalidad se puede proporcionar con un autenticador. Un autenticador es cualquier dispositivo respaldado por hardware o software que proporciona la capacidad de generar claves criptográficas. Piense en esas contraseñas de un solo uso que obtiene de google Authenticator1PasswordUltimo pase, entre otros.

Por ejemplo, un autenticador de software puede usar el Módulo de plataforma segura (TPM) o el enclave seguro de un dispositivo para crear credenciales. Las credenciales se pueden almacenar de forma remota y sincronizar entre dispositivos, por ejemplo, claves de acceso. Un autenticador de hardware sería algo así como un YubiKey, que puede generar y almacenar claves en el propio dispositivo.

Para acceder al autenticador, el navegador debe tener acceso al hardware y, para eso, necesitamos una interfaz. La interfaz que usamos aquí es el Protocolo de cliente a autenticador (CTAP). Permite el acceso a diferentes autenticadores a través de diferentes mecanismos. Por ejemplo, podemos acceder a un autenticador a través de NFC, USB y Bluetooth utilizando CTAP.

Una de las formas más interesantes de usar claves de acceso es conectando su teléfono a través de Bluetooth a otro dispositivo que podría no admitir claves de acceso. Cuando los dispositivos están emparejados a través de Bluetooth, ¡puedo iniciar sesión en el navegador de mi computadora usando mi teléfono como intermediario!

La diferencia entre claves de paso y WebAuthn

Las claves de paso y las claves de WebAuthn difieren de varias maneras. En primer lugar, las claves de acceso se consideran credenciales de varios dispositivos y se pueden sincronizar entre dispositivos. Por el contrario, las claves WebAuthn son credenciales de un solo dispositivo, una forma elegante de decir que está vinculado a un dispositivo para la verificación.

En segundo lugar, para autenticarse en un servidor, las claves WebAuthn deben proporcionar el identificador de usuario para iniciar sesión, después de lo cual un allowCredentials list se devuelve al cliente desde el servidor, lo que informa qué credenciales se pueden usar para iniciar sesión. Las claves de acceso se saltan este paso y usan el nombre de dominio del servidor para mostrar qué claves ya están vinculadas a ese sitio. Puede seleccionar la clave de acceso asociada con ese servidor, ya que su sistema ya la conoce.

De lo contrario, las claves son criptográficamente iguales; solo difieren en cómo se almacenan y qué información usan para iniciar el proceso de inicio de sesión.

El proceso... en pocas palabras

El proceso para generar un WebAuthn o una clave de paso es muy similar: obtenga un desafío del servidor y luego use el navigator.credentials.create API web para generar un par de claves públicas. Luego, envíe el desafío y la clave pública al servidor para que se almacenen.

Al recibir la clave pública y el desafío, el servidor valida el desafío y la sesión a partir de la cual se creó. Si eso se verifica, la clave pública se almacena, así como cualquier otra información relevante, como el identificador de usuario o los datos de atestación, en la base de datos.

El usuario tiene un paso más: recuperar otro desafío del servidor y usar el navigator.credentials.get API para firmar el desafío. Enviamos el desafío firmado al servidor, y el servidor verifica el desafío, luego nos registra si la firma pasa.

Por supuesto, hay un poco más en cada paso. Pero esa es generalmente la forma en que iniciaríamos sesión en un sitio web usando WebAuthn o claves de acceso.

la carne y las patatas

Las claves de acceso se utilizan en dos fases distintas: la certificación y afirmación fases

La fase de atestación también se puede considerar como la fase de registro. Te registrarías con un correo electrónico y una contraseña para un nuevo sitio web, sin embargo, en este caso, estaríamos usando nuestra clave de acceso.

La fase de afirmación es similar a cómo iniciaría sesión en un sitio web después de registrarse.

Atestación

Ver a tamaño completo

El  navigator.credentials.create API es el foco de nuestra fase de certificación. Estamos registrados como un nuevo usuario en el sistema y necesitamos generar un nuevo par de claves públicas. Sin embargo, debemos especificar qué tipo de par de claves queremos generar. Eso significa que tenemos que proporcionar opciones para navigator.credentials.create.

// The `challenge` is random and has to come from the server
const publicKey: PublicKeyCredentialCreationOptions = { challenge: safeEncode(challenge), rp: { id: window.location.host, name: document.title, }, user: { id: new TextEncoder().encode(crypto.randomUUID()), // Why not make it random? name: 'Your username', displayName: 'Display name in browser', }, pubKeyCredParams: [ { type: 'public-key', alg: -7, // ES256 }, { type: 'public-key', alg: -256, // RS256 }, ], authenticatorSelection: { userVerification: 'preferred', // Do you want to use biometrics or a pin? residentKey: 'required', // Create a resident key e.g. passkey }, attestation: 'indirect', // indirect, direct, or none timeout: 60_000,
};
const pubKeyCredential: PublicKeyCredential = await navigator.credentials.create({ publicKey
});
const { id // the key id a.k.a. kid
} = pubKeyCredential;
const pubKey = pubKeyCredential.response.getPublicKey();
const { clientDataJSON, attestationObject } = pubKeyCredential.response;
const { type, challenge, origin } = JSON.parse(new TextDecoder().decode(clientDataJSON));
// Send data off to the server for registration

Nosotros recibiremos PublicKeyCredential que contiene un AuthenticatorAttestationResponse que vuelve después de la creación. La credencial tiene el ID del par de claves generado.

La respuesta proporciona un par de bits de información útil. Primero, tenemos nuestra clave pública en esta respuesta y debemos enviarla al servidor para que la almacene. En segundo lugar, también recuperamos el clientDataJSON propiedad que podemos decodificar y, a partir de ahí, recuperar la typechallengeorigin de la clave de paso.

Para la atestación, queremos validar el typechallengeorigin en el servidor, así como almacenar la clave pública con su identificador, por ejemplo, kid. También podemos almacenar opcionalmente el attestationObject si lo deseamos Otra propiedad útil para almacenar es la CÓMODAMENTE algoritmo, que se define anteriormente en nuestro  PublicKeyCredentialCreationOptions   alg: -7 or alg: -256, para verificar fácilmente cualquier desafío firmado en la fase de aserción.

afirmación

Ver a tamaño completo

El  navigator.credentials.get API será el foco de la fase de aserción. Conceptualmente, aquí sería donde el usuario inicia sesión en la aplicación web después de registrarse.

// The `challenge` is random and has to come from the server
const publicKey: PublicKeyCredentialRequestOptions = { challenge: new TextEncoder().encode(challenge), rpId: window.location.host, timeout: 60_000,
};
const publicKeyCredential: PublicKeyCredential = await navigator.credentials.get({ publicKey, mediation: 'optional',
});
const { id // the key id, aka kid
} = pubKeyCredential;
const { clientDataJSON, attestationObject, signature, userHandle } = pubKeyCredential.response;
const { type, challenge, origin } = JSON.parse(new TextDecoder().decode(clientDataJSON));
// Send data off to the server for verification

Volveremos a obtener un PublicKeyCredential con una AuthenticatorAssertionResponse esta vez. La credencial nuevamente incluye el identificador de clave.

También obtenemos el typechallengeorigin del desplegable clientDataJSON otra vez. los signature ahora se incluye en la respuesta, así como la authenticatorData. Necesitaremos esos y el clientDataJSON para verificar que este fue firmado con la clave privada.

El  authenticatorData incluye algunas propiedades que vale la pena rastrear Primero es el hash SHA256 del origen que está utilizando, ubicado dentro de los primeros 32 bytes, que es útil para verificar que la solicitud proviene del mismo servidor de origen. El segundo es el signCount, que es del byte 33 al 37. Esto se genera a partir del autenticador y debe compararse con su valor anterior para garantizar que no ocurra nada sospechoso con la clave. El valor siempre debe ser 0 cuando se trata de una clave de paso de varios dispositivos y debe ser aleatoriamente mayor que el signCount anterior cuando se trata de una clave de paso de un solo dispositivo.

Una vez que haya afirmado su inicio de sesión, debe iniciar sesión: felicitaciones! Passkeys es un protocolo bastante bueno, pero viene con algunas advertencias.

Algunas desventajas

Hay muchas ventajas en Passkeys, sin embargo, hay algunos problemas al momento de escribir este artículo. Por un lado, las claves de acceso aún son un poco tempranas en cuanto a soporte, con solo credenciales de un solo dispositivo permitidas en Windows y muy poco soporte para sistemas Linux. Claves de paso.dev proporciona una bonita mesa que es algo así como el Caniuse de este protocolo.

Además, las plataformas de claves de acceso de Google y Apple no se comunican entre sí. Si desea transferir sus credenciales de su teléfono Android a su iPhone... bueno, no tiene suerte por ahora. ¡Eso no quiere decir que no haya interoperabilidad! Puede iniciar sesión en su computadora usando su teléfono como autenticador. Pero sería mucho más limpio tenerlo integrado en el sistema operativo y sincronizado sin que esté bloqueado en el nivel del proveedor.

¿Adónde van las cosas?

¿Cómo es el protocolo de claves de paso del futuro? ¡Se ve bastante bien! Una vez que gane soporte de más sistemas operativos, debería haber una aceptación en el uso, y comenzarás a ver que se usa cada vez más en la naturaleza. Alguno administradores de contraseñas incluso van a apoyarlos de primera mano.

Las claves de paso no solo se admiten en la web. Android y iOS ambos admitirán claves de paso nativas como ciudadanos de primera clase. Todavía estamos en los primeros días de todo esto, pero espere verlo mencionado cada vez más.

Después de todo, eliminamos la necesidad de contraseñas y, al hacerlo, ¡hacemos que el mundo sea más seguro!

Recursos

Aquí hay algunos recursos más si desea obtener más información sobre Passkeys. También hay un repositorio y una demostración que preparé para este artículo.

punto_img

Información más reciente

punto_img