作为 Android 开发者,您一直在寻找增强安全性、改善用户体验和简化开发的方法。Zoho 是一套全面的云端软件套件,专注于安全性和顺畅体验。通过在 OneAuth Android 应用中采用通行密钥,Zoho 取得了显著改进。
自 2024 年集成通行密钥以来,Zoho 的登录速度比以前的方法快了 6 倍 ,并且通行密钥采用率环比增长了 31% 。
本案例研究探讨了 Zoho 采用通行密钥和 Android 的 Credential Manager API 来解决身份验证难题的情况。它详细介绍了技术实现过程,并重点介绍了富有成效的结果。
克服身份验证难题
Zoho 采用多种身份验证方法来保护用户账号。其中包括 Zoho OneAuth(Zoho 自己的多重身份验证 (MFA) 解决方案),该解决方案支持基于密码的身份验证和无密码身份验证,方法包括推送通知、二维码和基于时间的动态密码 (TOTP)。Zoho 还支持联合登录,允许通过安全断言标记语言 (SAML) 和其他第三方身份提供方进行身份验证。
难题
与许多组织一样,Zoho 的目标是提高身份验证安全性和用户体验,同时减轻运营负担。促使 Zoho 采用通行密钥的主要难题包括:
- 安全漏洞:传统的基于密码的方法让用户容易受到钓鱼式攻击和密码泄露的影响。
- 用户摩擦:密码疲劳导致用户忘记密码,感到沮丧,并更加依赖繁琐的恢复流程。
- 运营效率低下:处理密码重置和 MFA 问题会产生大量支持开销。
- 可伸缩性问题:用户群不断增长,需要更安全、更高效的身份验证解决方案。
为何转向通行密钥?
Zoho 在其应用中实现了通行密钥,以解决身份验证难题,方法是提供无密码方法,从而显著提高安全性和用户体验。此解决方案利用了防范钓鱼式攻击的身份验证、云同步凭据(可轻松实现跨设备访问)以及生物识别(例如指纹或人脸识别)、PIN 码或解锁图案(可实现安全登录),从而减少了与传统密码相关的漏洞和不便。
通过采用通行密钥和 Credential Manager,Zoho 将登录时间缩短了多达 6 倍,大幅降低了与密码相关的支持费用,并且用户采用率很高 – 通行密钥登录次数在 4 个月内翻了一番,环比增长了 31% 。Zoho 用户现在可以享受更快速、更轻松的登录体验,以及防范钓鱼式攻击的安全性 。
在 Android 上使用 Credential Manager 实现
那么,Zoho 是如何取得这些成果的呢?他们使用了 Android 的 Credential Manager API,这是在 Android 上实现身份验证的推荐 Jetpack 库。
Credential Manager 提供了一个统一的 API,可简化各种身份验证方法的处理。您无需为密码、通行密钥和联合登录(例如“使用 Google 账号登录”)分别使用不同的 API,而是使用一个界面。
在 Zoho 实现通行密钥需要进行客户端和服务器端调整。下面详细介绍了通行密钥创建、登录和服务器端实现过程。
创建通行密钥
如需创建通行密钥,应用首先会从 Zoho 的服务器检索配置详细信息。此过程包括唯一的验证,例如指纹或人脸识别。此身份验证数据(格式为 requestJson 字符串)供应用用于构建 CreatePublicKeyCredentialRequest。然后,应用会调用 credentialManager.createCredential 方法,该方法会提示用户使用其设备屏幕锁定(生物识别、指纹、PIN 码等)进行身份验证。
用户成功确认后,应用会收到新的通行密钥凭据数据,并将其发送回 Zoho 的服务器进行验证,然后服务器会存储与用户账号关联的通行密钥信息。在此过程中发生的失败或用户取消操作会被应用捕获并处理。
登录
Zoho Android 应用会从 Zoho 的后端服务器请求登录选项(包括唯一的 challenge),从而启动 通行密钥登录过程。然后,应用会使用此数据构建 GetCredentialRequest,表明它将使用通行密钥进行身份验证。然后,它会使用此请求调用 Android CredentialManager.getCredential() API。此操作会触发标准化的 Android 系统界面,提示用户选择其 Zoho 账号(如果存在多个通行密钥),并使用其设备配置的屏幕锁定(指纹、人脸扫描或 PIN 码)进行身份验证。身份验证成功后,Credential Manager 会向 Zoho 应用返回已签名的断言(登录证明)。该应用会将此断言转发给 Zoho 的服务器,该服务器会根据用户存储的公钥验证签名并验证 challenge,从而完成安全登录过程。
服务器端实现
Zoho 的后端系统已符合 FIDO WebAuthn 标准,这简化了服务器端实现过程,有助于 Zoho 过渡到支持通行密钥。不过,仍需要进行特定修改才能完全集成通行密钥功能。
最重大的难题是调整凭证存储空间。Zoho 现有的身份验证方法主要使用密码和 FIDO 安全密钥进行多重身份验证,这需要与基于加密公钥的通行密钥不同的存储方法。为了解决这个问题,Zoho 实现了一个新的数据库架构,专门用于根据 WebAuthn 协议安全地存储通行密钥公钥和相关数据。此新系统是与查找机制一起构建的,用于根据用户和设备信息验证和检索凭据,确保与旧身份验证方法向后兼容。
另一项服务器端调整涉及实现处理来自 Android 设备的请求的功能。源自 Android 应用的通行密钥请求使用唯一的来源格式 (android:apk-key-hash:example),该格式不同于使用基于 URI 的格式 (https://example.com/app) 的标准 Web 来源。需要更新服务器逻辑,以正确解析此格式,提取应用签名证书的 SHA-256 指纹哈希,并根据预注册列表对其进行验证。此验证步骤可确保身份验证请求确实源自 Zoho 的 Android 应用,并防范钓鱼式攻击。
以下代码段演示了服务器如何检查特定于 Android 的来源格式并验证证书哈希:
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 } }
错误处理
Zoho 实现了强大的 错误处理机制,用于管理面向用户的错误和面向开发者的错误。当用户手动取消通行密钥设置时,会出现一个常见错误 CreateCredentialCancellationException。Zoho 跟踪此错误的频率,以评估潜在的 UX 改进。根据 Android 的 UX 建议,Zoho 采取了以下措施,以便更好地向用户介绍通行密钥,确保用户了解通行密钥的可用性,并在后续登录尝试中推广通行密钥。
以下代码示例演示了 Zoho 如何处理最常见的通行密钥创建错误:
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."
}
}
}在内网环境中测试通行密钥
Zoho 在封闭的内网环境中测试通行密钥时面临着最初的难题。通行密钥的 Google 密码管理工具 验证过程 需要公开网域访问权限才能验证依赖方 (RP) 网域。不过,Zoho 的内部测试环境缺少此公共互联网访问权限,导致验证流程失败,并阻碍了通行密钥身份验证测试的成功。为了克服这个问题,Zoho 创建了一个可公开访问的测试环境,其中包括托管一个临时服务器,其中包含一个 资产链接文件 和网域验证。
以下示例来自 Zoho 公开测试环境中使用的 assetlinks.json 文件,演示了如何将依赖方网域与指定的 Android 应用相关联以进行通行密钥验证。
[
{
"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"
]
}
}
]与现有 FIDO 服务器集成
Android 的通行密钥系统采用了最新的 FIDO2 WebAuthn 标准。此标准要求请求采用特定的 JSON 格式,这有助于保持原生应用和 Web 平台之间的一致性。为了启用 Android 通行密钥支持,Zoho 对兼容性和结构进行了细微更改,以正确生成和处理符合所需 FIDO2 JSON 结构的请求。
此服务器更新涉及多项具体的技术调整:
1. 编码转换: 服务器在存储相关数据之前,会将 Base64 网址编码(通常在 WebAuthn 中用于凭据 ID 等字段)转换为标准 Base64 编码。以下代码段展示了如何将 rawId 编码为标准 Base64:
// Convert rawId bytes to a standard Base64 encoded string for storage val base64RawId: String = Base64.getEncoder().encodeToString(rawId.toByteArray())
2. 传输列表格式: 为了确保数据处理的一致性,服务器逻辑会将传输机制列表(例如 USB、NFC 和蓝牙,它们指定了身份验证器如何通信)作为 JSON 数组进行处理。
3. 客户端数据对齐: Zoho 团队调整了服务器对 clientDataJson 字段进行编码和解码的方式。这可确保数据结构与 Zoho 现有内部 API 的预期完全一致。以下示例说明了服务器处理客户端数据之前应用于客户端数据的部分转换逻辑:
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()) }
用户指南和身份验证偏好设置
Zoho 通行密钥策略的核心部分包括鼓励用户采用,同时提供灵活性以符合不同的组织要求。这是通过精心设计的界面和政策控制来实现的。
Zoho 认识到,组织的安全需求各不相同。为了适应这一点,Zoho 实现了以下功能:
- 管理员强制执行: 通过 Zoho Directory 管理面板,管理员可以将通行密钥指定为其整个组织的强制性默认身份验证方法。启用此政策后,员工需要在下次登录时设置通行密钥,并继续使用该通行密钥。
- 用户选择: 如果组织未强制执行特定政策,则个人用户将保留控制权。他们可以在登录时选择自己偏好的身份验证方法,通过身份验证设置从通行密钥或其他配置的选项中进行选择。
为了让最终用户轻松采用通行密钥,Zoho 实现了以下功能:
- 轻松设置: Zoho 将通行密钥设置直接集成到了 Zoho OneAuth 移动应用(适用于 Android 和 iOS)。用户可以随时在应用内方便地配置通行密钥,从而顺利完成过渡。
- 一致的访问权限: 通行密钥支持已在关键用户接触点实现,确保用户可以通过以下方式使用通行密钥进行注册和身份验证:
- Zoho OneAuth 移动应用(Android 和 iOS);
- Zoho Web 账号页面。
无论是由管理员强制执行还是由用户选择,此方法都可确保设置和使用通行密钥的过程可访问且已集成到用户已使用的平台中。如需详细了解如何为通行密钥身份验证创建顺畅的用户流程,请参阅我们全面的 通行密钥用户体验指南。
对开发者速度和集成效率的影响
Credential Manager 作为统一的 API,还有助于提高开发者工作效率,与旧的登录流程相比,它降低了单独处理多种身份验证方法和 API 的复杂性,从而将集成速度从数月缩短至数周,并减少了实现错误。它降低了分别处理多种身份验证方法和 API 的复杂性,从而将集成时间从数月缩短至数周,并减少了实现错误。这共同简化了登录过程并提高了整体可靠性。
通过使用 Credential Manager 实现通行密钥,Zoho 在各个方面都取得了显著且可衡量的改进:
- 速度大幅提升
- 与传统的密码身份验证相比,登录速度快了 2 倍 。
- 与使用用户名或手机号码以及电子邮件或短信动态密码身份验证相比,登录速度快了 4 倍 。
- 与使用用户名、密码以及短信或身份验证器动态密码身份验证相比,登录速度快了 6 倍 。
- 降低了支持费用
- 与密码相关的支持请求减少了,尤其是忘记密码的情况。
- 与基于短信的两步验证相关的费用降低了 ,因为现有用户可以直接使用通行密钥进行登录。
- 用户采用率高,安全性增强:
- 通行密钥登录次数在短短 4 个月内翻了一番 ,表明用户接受度很高。
- 迁移到通行密钥的用户完全免受 常见的钓鱼式攻击和密码泄露威胁。
- 随着采用率环比增长 31%,每天都有更多用户受益于针对钓鱼式攻击和 SIM 卡交换等漏洞的增强安全性。
建议和最佳实践
如需在 Android 上成功实现通行密钥,开发者应考虑以下最佳实践:
- 利用 Android 的 Credential Manager API:
- Credential Manager 简化了凭据检索,减少了开发者的工作量,并确保了统一的身份验证体验。
- 在单个界面中处理密码、通行密钥和联合登录流程。
- 在从其他 FIDO 身份验证解决方案迁移时,确保数据编码一致性:
- 确保在从其他 FIDO 身份验证解决方案(例如 FIDO 安全密钥)迁移时,处理所有输入/输出的一致格式。
- 优化错误处理和日志记录:
- 实现强大的错误处理机制,以提供顺畅的用户体验。
- 提供本地化的错误消息,并使用详细的日志来调试和解决意外失败。
- 向用户介绍通行密钥账号恢复选项:
- 主动向用户介绍账号恢复选项,防止出现锁定情况。
- 监控采用指标和用户反馈:
- 跟踪用户互动度、通行密钥采用率和登录成功率,以便不断优化用户体验。
- 对不同的身份验证流程进行 A/B 测试,以提高转化率和用户留存率。
通行密钥与 Android Credential Manager API 相结合,提供了一个强大且统一的身份验证解决方案,可在简化用户体验的同时增强安全性。通行密钥可显著降低钓鱼式攻击风险、凭据盗窃和未经授权的访问。我们鼓励开发者在自己的应用中试用该体验,并为用户提供最安全的身份验证。
通行密钥和 Credential Manager 使用入门
使用我们的 公开示例代码,在 Android 上亲身体验通行密钥和 Credential Manager。
如果您有任何疑问或问题,可以通过 Android 凭据问题跟踪器 与我们分享。
继续阅读
-
案例研究
Uber 利用 Android Restore Credentials API 简化了新设备的登录流程,预计每年可减少 400 万次手动登录,并提高用户留存率。
Niharika Arora • 阅读时间:5 分钟
-
案例研究
X 是一款社交媒体应用,旨在帮助全球近 5 亿用户获取重大新闻和娱乐资讯,以及体育和政治方面的实时评论。
Niharika Arora • 阅读时间:3 分钟
-
案例研究
Monzo 是一家英国数字银行,拥有 1500 万客户,并且还在不断增长。随着应用规模的扩大,工程团队发现应用启动时间是一个需要改进的关键领域,但担心这需要对代码库进行重大更改。
Ben Weiss • 阅读时间:2 分钟
随时了解最新动态
每周通过电子邮件接收最新的 Android 开发洞见 每周。