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, la experiencia del usuario y optimizar el desarrollo. Zoho, un paquete de software integral basado en la nube que se centra en la seguridad y las experiencias fluidas, logró mejoras significativas al adoptar llaves de acceso en su OneAuth app para Android.

Desde que integró las llaves de acceso en 2024, Zoho logró velocidades de acceso hasta 6 veces más rápidas que los métodos anteriores y un crecimiento intermensual (MoM) del 31% 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. Se detalla el proceso de implementación técnica y se destacan 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 incluye Zoho OneAuth, su propia solución de autenticación de varios factores (MFA), que admite la autenticación basada en contraseñas y sin contraseñas mediante notificaciones push, códigos QR y contraseñas de un solo uso basadas en el tiempo (TOTP). Zoho también admite accesos federados, lo que permite la autenticación a través del lenguaje de marcado para confirmaciones de seguridad (SAML) y otros proveedores de identidad externos.

Desafíos

Zoho, al igual que muchas organizaciones, buscaba mejorar la seguridad de la autenticación y la experiencia del usuario, a la vez que reducía las cargas operativas. Los principales desafíos que llevaron a la adopción de llaves de acceso fueron 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 provocaba que se olvidaran las contraseñas, frustración y una mayor dependencia de procesos de recuperación engorrosos.
  • Ineficiencias operativas: El manejo de los restablecimientos de contraseñas y los problemas de MFA generaba una sobrecarga de asistencia significativa.
  • Problemas de escalabilidad: Una base de usuarios en crecimiento exigía una solución de autenticación más segura y eficiente.

¿Por qué el cambio a las llaves de acceso?

Las llaves de acceso se implementaron en las apps de Zoho para abordar los desafíos de autenticación ofreciendo 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 multidispositivo sin esfuerzo y la biometría (como la huella dactilar o el reconocimiento facial), el PIN o el patrón para accesos seguros, lo que reduce las vulnerabilidades y los inconvenientes asociados con las contraseñas tradicionales.

Al adoptar 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 sólida adopción por parte de los usuarios, duplicando los accesos con llaves de acceso en 4 meses con un crecimiento intermensual del 31% . Los usuarios de Zoho ahora disfrutan de accesos 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? Usó 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 hacer malabares con 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 del cliente y del servidor. A continuación, se incluye un desglose detallado del proceso de creación de llaves de acceso, acceso y la implementación del servidor.

Creación de llaves de acceso

passkey.png

Para crear una llave de acceso, la app primero 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 el formato de una cadena requestJson, para compilar una 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 (biometría, huella dactilar, PIN, etc.).

Una vez que 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.

Acceso

La app para Android de Zoho inicia el proceso de acceso con llaves de acceso solicitando opciones de acceso, incluido un challenge, desde el servidor de backend de Zoho. Luego, la app usa estos datos para crear una 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, escaneo facial o PIN). Después de la autenticación correcta, Credential Manager muestra 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 optimizó el proceso de implementación del servidor. Sin embargo, aún eran necesarias modificaciones específicas para integrar por completo la funcionalidad de las llaves 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 usaban principalmente contraseñas y llaves de seguridad FIDO para la autenticación de varios factores, requerían enfoques de almacenamiento diferentes a 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 en función de la información del usuario y del dispositivo, lo que garantiza la retrocompatibilidad con métodos de autenticación más antiguos.

Otro ajuste del servidor implicó implementar la capacidad de controlar solicitudes de dispositivos Android. Las solicitudes de llaves 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). Se debió actualizar la lógica del servidor para analizar correctamente este formato, extraer el hash de huella digital SHA-256 del certificado de firma de la app y validarlo con una lista pre registrada. Este paso de verificación garantiza que las solicitudes de autenticación se originen realmente 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 desarrolladores. Apareció un error común, CreateCredentialCancellationException, cuando los usuarios cancelaron manualmente la configuración de su 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 los usuarios conocieran la disponibilidad de las llaves de acceso y promover la adopción de llaves de acceso durante los intentos de acceso posteriores.

En este ejemplo de código, se muestra el enfoque de Zoho para manejar los errores más comunes de 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."
        }
    }
}

Prueba de llaves de acceso en entornos de intranet

Zoho enfrentó un desafío inicial en la prueba de llaves de acceso dentro de un entorno de intranet cerrado. El proceso de verificación del Administrador de contraseñas de Google para 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 dificultara la prueba de autenticación de llaves de acceso exitosa. Para superar este problema, Zoho creó un entorno de pruebas de acceso público, que incluía alojar un servidor temporal con un archivo de vínculo de recursos y validación de dominio.

En este ejemplo del archivo assetlinks.json que se usa en el entorno de pruebas 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 llaves 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ó cambios menores de compatibilidad y estructurales para generar y procesar correctamente las solicitudes que cumplen con la estructura JSON 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 Base64 (que se usa de uso frecuente en WebAuthn para campos como los IDs de credenciales) a la codificación Base64 estándar antes de almacenar los datos pertinentes. En el siguiente fragmento, se muestra cómo se puede 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 lista de transporte: Para garantizar el procesamiento coherente de los datos, 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 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 aplicada 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())
}

Guía del usuario y preferencias de autenticación

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

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

  • Aplicación 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 obligatorio y predeterminado para toda su organización. Cuando se habilita esta política, los empleados deben configurar una llave de acceso en su próximo acceso 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, seleccionando entre llaves de acceso u otras opciones configuradas a través de 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 llaves 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 en cualquier momento, lo que facilita la transición.
  • Acceso coherente: Se implementó la compatibilidad con llaves de acceso en los puntos de contacto clave del usuario, lo que garantiza que los usuarios puedan registrarse y autenticarse con llaves de acceso a través de lo siguiente:
  • La app para dispositivos móviles de Zoho OneAuth (iOS y Android)
  • La página web de cuentas 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 ordenó un administrador o lo eligió el usuario. Para obtener más información sobre cómo crear flujos de usuarios fluidos para la autenticación con llaves de acceso, explora nuestra guía integral de experiencia del usuario de llaves de acceso.

Impacto en la velocidad del desarrollador y la eficiencia de la integración

Credential Manager, como una API unificada, también ayudó a mejorar la productividad de los desarrolladores en comparación con los flujos de acceso más antiguos. Redujo la complejidad de manejar varios métodos de autenticación y APIs por separado, lo que generó 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.

Al implementar llaves de acceso con Credential Manager, Zoho logró mejoras significativas y medibles en todos los aspectos:

  • Mejoras drásticas en la velocidad
    • Acceso 2 veces más rápido en comparación con la autenticación tradicional con contraseña
    • Acceso 4 veces más rápido en comparación con el nombre de usuario o el número de teléfono con la autenticación de OTP por correo electrónico o SMS
    • Acceso 6 veces más rápido en comparación con el nombre de usuario, la contraseña y la autenticación de OTP por SMS o autenticador
  • Reducción de los costos de asistencia
    • Reducción de las solicitudes de asistencia relacionadas con contraseñas, en especial para contraseñas olvidadas
    • Menores costos asociados con la 2FA basada en SMS, ya que los usuarios existentes pueden incorporarse directamente con llaves de acceso
  • Sólida adopción por parte de los usuarios y seguridad mejorada:
    • Los accesos con llaves de acceso se duplicaron en solo 4 meses, lo que demuestra una alta aceptación por parte de los usuarios.
    • Los usuarios que migran a llaves de acceso están completamente protegidos de las amenazas comunes de phishing y violación de contraseñas.
    • Con un crecimiento intermensual del 31% en la adopción, cada vez más usuarios se benefician de una mayor seguridad contra vulnerabilidades como el phishing y los intercambios 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:
    • Credential Manager simplifica la recuperación de credenciales, reduce el esfuerzo del desarrollador y garantiza una experiencia de autenticación unificada.
    • Controla las contraseñas, las llaves de acceso y los flujos de acceso federado en una sola interfaz.
  • Garantiza la coherencia de la codificación de datos mientras migras desde otras soluciones de autenticación FIDO:
    • Asegúrate de controlar el formato coherente para todas las entradas y salidas mientras migras 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 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 de forma proactiva a los usuarios 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, el robo de credenciales y el acceso no autorizado. Recomendamos a los desarrolladores que prueben la experiencia en su app y brinden la autenticación más segura a sus usuarios.

Comienza a usar llaves de acceso y Credential Manager

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

Si tienes alguna pregunta o problema, puedes compartirla con nosotros a través del registro de problemas de credenciales de Android.

Escrito por:

Seguir leyendo