Casos de éxito

Zoho logra accesos 6 veces más rápidos con la integración de llaves de acceso y Credential Manager

Lectura de 10 min

Como desarrollador de Android, siempre buscas formas de mejorar la seguridad, optimizar la experiencia del usuario y agilizar el desarrollo. Zoho, un paquete de software integral basado en la nube que se enfoca en la seguridad y las experiencias fluidas, logró mejoras significativas al adoptar llaves de acceso en su app para Android OneAuth.

Desde que integró las llaves de acceso en 2024, Zoho logró velocidades de acceso hasta 6 veces más rápidas que con los métodos anteriores y un crecimiento del 31% mes a mes en la adopción de llaves de acceso.

En este caso de éxito, se analiza la adopción de llaves de acceso y la API de Credential Manager de Android por parte de Zoho para abordar las dificultades de autenticación. Detalla el proceso de implementación técnica y destaca los resultados impactantes.

Cómo superar los desafíos de autenticación

Zoho utiliza una combinación de métodos de autenticación para proteger las cuentas de usuario. Esto incluía Zoho OneAuth, su propia solución de autenticación de varios factores (MFA), que admitía la autenticación basada en contraseñas y sin contraseñas con notificaciones push, códigos QR y contraseñas de un solo uso basadas en el tiempo (TOTP). Zoho también admitía inicios de sesión federados, lo que permitía la autenticación a través del lenguaje de marcado para confirmaciones de seguridad (SAML) y otros proveedores de identidad externos.

Desafíos

Al igual que muchas organizaciones, Zoho buscaba mejorar la seguridad de la autenticación y la experiencia del usuario, a la vez que reducía las cargas operativas. Entre los principales desafíos que llevaron a la adopción de las llaves de acceso, se incluyen los siguientes:

  • Vulnerabilidades de seguridad: Los métodos tradicionales basados en contraseñas dejaban a los usuarios expuestos a ataques de phishing y violaciones de contraseñas.
  • Fricción del usuario: La fatiga de contraseñas provocó que se olvidaran las contraseñas, frustración y una mayor dependencia de procesos de recuperación engorrosos.
  • Ineficiencias operativas: El manejo de restablecimientos de contraseñas y problemas de MFA generó una sobrecarga significativa en la asistencia.
  • Problemas de escalabilidad: Una base de usuarios en crecimiento exigía una solución de autenticación más segura y eficiente.

¿Por qué cambiamos a las llaves de acceso?

Las llaves de acceso se implementaron en las apps de Zoho para abordar los desafíos de autenticación, ya que ofrecen un enfoque sin contraseñas que mejora significativamente la seguridad y la experiencia del usuario. Esta solución aprovecha la autenticación resistente al phishing, las credenciales sincronizadas en la nube para un acceso sin esfuerzo multidispositivo y los datos biométricos (como la huella dactilar o el reconocimiento facial), el PIN o el patrón para inicios de sesión seguros, lo que reduce las vulnerabilidades y los inconvenientes asociados con las contraseñas tradicionales.

Al adoptar las llaves de acceso con Credential Manager, Zoho redujo los tiempos de acceso hasta 6 veces, disminuyó los costos de asistencia relacionados con las contraseñas y observó una gran adopción por parte de los usuarios, ya que duplicó los accesos con llave de acceso en 4 meses con un crecimiento del 31% mes a mes. Ahora, los usuarios de Zoho disfrutan de inicios de sesión más rápidos y sencillos, y de seguridad resistente al phishing.

ANDDM_Zoho_Quote_fabrice.png

Implementación con Credential Manager en Android

Entonces, ¿cómo logró Zoho estos resultados? Usaron la API de Credential Manager de Android, la biblioteca de Jetpack recomendada para implementar la autenticación en Android.

Credential Manager proporciona una API unificada que simplifica el manejo de los diversos métodos de autenticación. En lugar de usar diferentes APIs para contraseñas, llaves de acceso y accesos federados (como Acceder con Google), usas una sola interfaz.

La implementación de llaves de acceso en Zoho requirió ajustes tanto del lado del cliente como del servidor. A continuación, se incluye un desglose detallado del proceso de creación, acceso y de implementación del servidor de las llaves de acceso.

Creación de llaves de acceso

passkey.png

Para crear una llave de acceso, primero la app recupera los detalles de configuración del servidor de Zoho. Este proceso incluye una verificación única, como una huella dactilar o el reconocimiento facial. La app usa estos datos de verificación, con formato de cadena requestJson, para compilar un objeto CreatePublicKeyCredentialRequest. Luego, la app llama al método credentialManager.createCredential, que le solicita al usuario que se autentique con el bloqueo de pantalla de su dispositivo (datos biométricos, huella digital, PIN, etcétera).

Cuando el usuario confirma correctamente, la app recibe los nuevos datos de credenciales de la llave de acceso, los envía de vuelta al servidor de Zoho para su verificación y, luego, el servidor almacena la información de la llave de acceso vinculada a la cuenta del usuario. La app detecta y controla las fallas o las cancelaciones del usuario durante el proceso.

Acceder

La app para Android de Zoho inicia el proceso de acceso con llave de acceso solicitando opciones de acceso, incluida una challenge única, desde el servidor de backend de Zoho. Luego, la app usa estos datos para construir un objeto GetCredentialRequest, lo que indica que se autenticará con una llave de acceso. Luego, invoca la API de CredentialManager.getCredential() de Android con esta solicitud. Esta acción activa una interfaz estandarizada del sistema Android, que le solicita al usuario que elija su cuenta de Zoho (si existen varias llaves de acceso) y que se autentique con el bloqueo de pantalla configurado de su dispositivo (huella dactilar, análisis facial o PIN). Después de la autenticación exitosa, Credential Manager devuelve una aserción firmada (prueba de acceso) a la app de Zoho. La app reenvía esta aserción al servidor de Zoho, que verifica la firma con la clave pública almacenada del usuario y valida el desafío, lo que completa el proceso de acceso seguro.

Implementación del servidor

La transición de Zoho para admitir llaves de acceso se benefició de que sus sistemas de backend ya cumplían con FIDO WebAuthn, lo que agilizó el proceso de implementación del servidor. Sin embargo, aún eran necesarias modificaciones específicas para integrar por completo la funcionalidad de la llave de acceso.

El desafío más importante fue adaptar el sistema de almacenamiento de credenciales. Los métodos de autenticación existentes de Zoho, que principalmente usaban contraseñas y llaves de seguridad FIDO para la autenticación de varios factores, requerían enfoques de almacenamiento diferentes a los de las llaves de acceso, que se basan en claves públicas criptográficas. Para abordar este problema, Zoho implementó un nuevo esquema de base de datos diseñado específicamente para almacenar de forma segura las claves públicas de las llaves de acceso y los datos relacionados según los protocolos de WebAuthn. Este nuevo sistema se creó junto con un mecanismo de búsqueda para validar y recuperar credenciales según la información del usuario y el dispositivo, lo que garantiza la retrocompatibilidad con métodos de autenticación anteriores.

Otro ajuste del servidor implicó implementar la capacidad de controlar solicitudes de dispositivos Android. Las solicitudes de llave de acceso que se originan en apps para Android usan un formato de origen único (android:apk-key-hash:example) que es distinto de los orígenes web estándar que usan un formato basado en URI (https://example.com/app). La lógica del servidor debió actualizarse para analizar correctamente este formato, extraer el hash de la huella digital SHA-256 del certificado de firma de la app y validarlo en una lista pre registrada. Este paso de verificación garantiza que las solicitudes de autenticación se originen genuinamente en la app para Android de Zoho y protege contra ataques de phishing.

En este fragmento de código, se muestra cómo el servidor verifica el formato de origen específico de Android y valida el hash del certificado:

val origin: String = clientData.getString("origin")

if (origin.startsWith("android:apk-key-hash:")) { 
    val originSplit: List<String> = origin.split(":")
    if (originSplit.size > 3) {
               val androidOriginHashDecoded: ByteArray = Base64.getDecoder().decode(originSplit[3])

                if (!androidOriginHashDecoded.contentEquals(oneAuthSha256FingerPrint)) {
            throw IAMException(IAMErrorCode.WEBAUTH003)
        }
    } else {
        // Optional: Handle the case where the origin string is malformed    }
}

Manejo de errores

Zoho implementó mecanismos sólidos de manejo de errores para administrar los errores que ven los usuarios y los que ven los desarrolladores. Se produjo un error común, CreateCredentialCancellationException, cuando los usuarios cancelaron manualmente la configuración de la llave de acceso. Zoho hizo un seguimiento de la frecuencia de este error para evaluar posibles mejoras en la UX. Según las recomendaciones de UX de Android, Zoho tomó medidas para educar mejor a sus usuarios sobre las llaves de acceso, asegurarse de que conocieran su disponibilidad y promover su adopción durante los intentos de acceso posteriores.

En este ejemplo de código, se muestra el enfoque de Zoho para controlar los errores más comunes en la creación de llaves de acceso:

private fun handleFailure(e: CreateCredentialException) {
    val msg = when (e) {
        is CreateCredentialCancellationException -> {
            Analytics.addAnalyticsEvent(eventProtocol: "PASSKEY_SETUP_CANCELLED", GROUP_NAME)
            Analytics.addNonFatalException(e)
            "The operation was canceled by the user."
        }
        is CreateCredentialInterruptedException -> {
            Analytics.addAnalyticsEvent(eventProtocol: "PASSKEY_SETUP_INTERRUPTED", GROUP_NAME)
            Analytics.addNonFatalException(e)
            "Passkey setup was interrupted. Please try again."
        }
        is CreateCredentialProviderConfigurationException -> {
            Analytics.addAnalyticsEvent(eventProtocol: "PASSKEY_PROVIDER_MISCONFIGURED", GROUP_NAME)
            Analytics.addNonFatalException(e)
            "Credential provider misconfigured. Contact support."
        }
        is CreateCredentialUnknownException -> {
            Analytics.addAnalyticsEvent(eventProtocol: "PASSKEY_SETUP_UNKNOWN_ERROR", GROUP_NAME)
            Analytics.addNonFatalException(e)
            "An unknown error occurred during Passkey setup."
        }
        is CreatePublicKeyCredentialDomException -> {
            Analytics.addAnalyticsEvent(eventProtocol: "PASSKEY_WEB_AUTHN_ERROR", GROUP_NAME)
            Analytics.addNonFatalException(e)
            "Passkey creation failed: ${e.domError}"
        }
        else -> {
            Analytics.addAnalyticsEvent(eventProtocol: "PASSKEY_SETUP_FAILED", GROUP_NAME)
            Analytics.addNonFatalException(e)
            "An unexpected error occurred. Please try again."
        }
    }
}

Cómo probar llaves de acceso en entornos de intranet

Zoho enfrentó un desafío inicial para probar las llaves de acceso en un entorno de intranet cerrado. El proceso de verificación del Administrador de contraseñas de Google para las llaves de acceso requiere acceso al dominio público para validar el dominio de la parte que confía (RP). Sin embargo, el entorno de pruebas interno de Zoho no tenía este acceso público a Internet, lo que provocó que fallara el proceso de verificación y dificultó las pruebas de autenticación con llave de acceso. Para superar este problema, Zoho creó un entorno de prueba de acceso público, que incluía el alojamiento de un servidor temporal con un archivo de vínculo de recursos y la validación del dominio.

En este ejemplo del archivo assetlinks.json que se usa en el entorno de prueba público de Zoho, se muestra cómo asociar el dominio de la parte que confía con la app para Android especificada para la validación de la llave de acceso.

[
    {
        "relation": [
            "delegate_permission/common.handle_all_urls",
            "delegate_permission/common.get_login_creds"
        ],
        "target": {
            "namespace": "android_app",
            "package_name": "com.zoho.accounts.oneauth",
            "sha256_cert_fingerprints": [
                "SHA_HEX_VALUE" 
            ]
        }
    }
]

Integración con un servidor FIDO existente

El sistema de llaves de acceso de Android utiliza el estándar moderno FIDO2 WebAuthn. Este estándar requiere solicitudes en un formato JSON específico, lo que ayuda a mantener la coherencia entre las aplicaciones nativas y las plataformas web. Para habilitar la compatibilidad con llaves de acceso de Android, Zoho realizó pequeños cambios estructurales y de compatibilidad para generar y procesar correctamente las solicitudes que cumplen con la estructura JSON de FIDO2 requerida.

Esta actualización del servidor implicó varios ajustes técnicos específicos:

1. Conversión de codificación: El servidor convierte la codificación de URL en Base64 (que se usa de uso frecuente en WebAuthn para campos como los IDs de credenciales) en la codificación Base64 estándar antes de almacenar los datos pertinentes. En el siguiente fragmento, se muestra cómo se podría codificar un rawId en Base64 estándar:

// Convert rawId bytes to a standard Base64 encoded string for storage
val base64RawId: String = Base64.getEncoder().encodeToString(rawId.toByteArray())

2. Formato de la lista de transporte: Para garantizar un procesamiento de datos coherente, la lógica del servidor controla las listas de mecanismos de transporte (como USB, NFC y Bluetooth, que especifican cómo se comunicó el autenticador) como arrays JSON.

3. Alineación de los datos del cliente: El equipo de Zoho ajustó la forma en que el servidor codifica y decodifica el campo clientDataJson. Esto garantiza que la estructura de datos se alinee con precisión con las expectativas de las APIs internas existentes de Zoho. En el siguiente ejemplo, se ilustra parte de la lógica de conversión que se aplica a los datos del cliente antes de que el servidor los procese:

private fun convertForServer(type: String): String {
    val clientDataBytes = BaseEncoding.base64().decode(type)
    val clientDataJson = JSONObject(String(clientDataBytes, StandardCharsets.UTF_8))
    val clientJson = JSONObject()
    val challengeFromJson = clientDataJson.getString("challenge")
    // 'challenge' is a technical identifier/token, not localizable text.
    clientJson.put("challenge", BaseEncoding.base64Url()
        .encode(challengeFromJson.toByteArray(StandardCharsets.UTF_8))) 

    clientJson.put("origin", clientDataJson.getString("origin"))
    clientJson.put("type", clientDataJson.getString("type"))
    clientJson.put("androidPackageName", clientDataJson.getString("androidPackageName"))
    return BaseEncoding.base64().encode(clientJson.toString().toByteArray())
}

Orientación para el usuario y preferencias de autenticación

Una parte central de la estrategia de llaves de acceso de Zoho consistió en fomentar la adopción por parte de los usuarios y, al mismo tiempo, brindar flexibilidad para alinearse con los diferentes requisitos de la organización. Esto se logró a través de un diseño de IU y controles de políticas cuidadosos.

Zoho reconoció que las organizaciones tienen diferentes necesidades de seguridad. Para adaptarse a esta situación, Zoho implementó lo siguiente:

  • Aplicación obligatoria por parte del administrador: A través del panel de administración de Zoho Directory, los administradores pueden designar las llaves de acceso como el método de autenticación predeterminado y obligatorio para toda su organización. Cuando se habilita esta política, los empleados deben configurar una llave de acceso en su próximo inicio de sesión y usarla en el futuro.
  • Elección del usuario: Si una organización no aplica una política específica, los usuarios individuales mantienen el control. Pueden elegir su método de autenticación preferido durante el acceso, ya sea con llaves de acceso o con otras opciones configuradas en la configuración de autenticación.

Para que la adopción de llaves de acceso sea atractiva y sencilla para los usuarios finales, Zoho implementó lo siguiente:

  • Configuración sencilla: Zoho integró la configuración de la llave de acceso directamente en la app para dispositivos móviles de Zoho OneAuth (disponible para Android y iOS). Los usuarios pueden configurar sus llaves de acceso en la app de forma conveniente en cualquier momento, lo que facilita la transición.
  • Acceso coherente: Se implementó la compatibilidad con llaves de acceso en los principales puntos de contacto con el usuario, lo que garantiza que los usuarios puedan registrarse y autenticarse con llaves de acceso a través de los siguientes medios:
  • La app para dispositivos móviles de Zoho OneAuth (iOS y Android)
  • Su página de cuentas web de Zoho

Este método garantizó que el proceso de configuración y uso de llaves de acceso fuera accesible y se integrara en las plataformas que ya usan, independientemente de si lo exigía un administrador o lo elegía el usuario. Puedes obtener más información para crear flujos de usuarios fluidos para la autenticación con llaves de acceso en nuestra completa guía de experiencia del usuario con llaves de acceso.

Impacto en la velocidad de desarrollo y la eficiencia de la integración

Credential Manager, como API unificada, también ayudó a mejorar la productividad de los desarrolladores en comparación con los flujos de acceso anteriores. Se redujo la complejidad del manejo de varios métodos de autenticación y APIs por separado, lo que permitió una integración más rápida, de meses a semanas, y menos errores de implementación. En conjunto, esto optimizó el proceso de acceso y mejoró la confiabilidad general.

Con la implementación de llaves de acceso con Credential Manager, Zoho logró mejoras significativas y medibles en todos los aspectos:

  • Mejoras drásticas en la velocidad
    • El acceso es 2 veces más rápido en comparación con la autenticación tradicional con contraseña.
    • El inicio de sesión es 4 veces más rápido en comparación con el nombre de usuario o el número de celular con la autenticación por OTP por correo electrónico o SMS.
    • Acceso 6 veces más rápido en comparación con la autenticación con nombre de usuario, contraseña y OTP por SMS o autenticador.
  • Reducción de costos de asistencia
    • Se redujeron las solicitudes de asistencia relacionadas con contraseñas, en especial las de contraseñas olvidadas.
    • Menores costos asociados con la A2F basada en SMS, ya que los usuarios existentes pueden incorporarse directamente con llaves de acceso.
  • Gran adopción por parte de los usuarios y seguridad mejorada:
    • En solo 4 meses, se duplicaron los accesos con llave de acceso, lo que demuestra una gran aceptación por parte de los usuarios.
    • Los usuarios que migran a las llaves de acceso están totalmente protegidos de las amenazas comunes de phishing y violaciones de contraseñas.
    • Con un crecimiento del 31% en la adopción mes a mes, cada día más usuarios se benefician de la seguridad mejorada contra vulnerabilidades como el phishing y el intercambio de SIM.

Prácticas recomendadas y sugerencias

Para implementar correctamente las llaves de acceso en Android, los desarrolladores deben tener en cuenta las siguientes prácticas recomendadas:

  • Aprovecha la API de Credential Manager de Android:
    • El Administrador de credenciales simplifica la recuperación de credenciales, lo que reduce el esfuerzo de los desarrolladores y garantiza una experiencia de autenticación unificada.
    • Controla los flujos de acceso federado, las contraseñas y las llaves de acceso en una sola interfaz.
  • Garantiza la coherencia de la codificación de datos durante la migración desde otras soluciones de autenticación FIDO:
    • Asegúrate de controlar el formato coherente de todas las entradas y salidas cuando migres desde otras soluciones de autenticación FIDO, como las llaves de seguridad FIDO.
  • Optimiza el manejo de errores y el registro:
    • Implementa un manejo de errores sólido para brindar una experiencia del usuario fluida.
    • Proporciona mensajes de error localizados y usa registros detallados para depurar y resolver fallas inesperadas.
  • Informa a los usuarios sobre las opciones de recuperación de llaves de acceso:
    • Evita situaciones de bloqueo guiando a los usuarios de forma proactiva sobre las opciones de recuperación.
  • Supervisa las métricas de adopción y los comentarios de los usuarios:
    • Haz un seguimiento de la participación de los usuarios, las tasas de adopción de llaves de acceso y las tasas de éxito de acceso para seguir optimizando la experiencia del usuario.
    • Realiza pruebas A/B en diferentes flujos de autenticación para mejorar la conversión y la retención.

Las llaves de acceso, combinadas con la API de Credential Manager de Android, ofrecen una solución de autenticación potente y unificada que mejora la seguridad y simplifica la experiencia del usuario. Las llaves de acceso reducen significativamente los riesgos de phishing, robo de credenciales y acceso no autorizado. Alentamos a los desarrolladores a probar la experiencia en sus apps y brindar la autenticación más segura a sus usuarios.

Comienza a usar llaves de acceso y el Administrador de credenciales

Usa llaves de acceso y Credential Manager en Android con nuestro código de muestra público.

Si tienes alguna pregunta o problema, puedes compartirlo con nosotros a través del Android Credentials issues tracker.

Escrito por:

Seguir leyendo