询问将敏感数据存储到WebAuthN userHandle的安全性问题
更新于2024年2月28日
- 已知首个问题:user handle(id)的长度限制为64字节
根据相关讨论,认证器可能不会将id视为敏感信息(不过我的测试未找到相关证据)
我刚开发了一款基于客户端的2FA应用。我希望它仅在客户端运行,无需服务器,用户数据将存储在客户端的安全容器中,并可(加密后)同步至Google Drive应用数据文件夹,该文件夹需结合API密钥与用户OAuth2令牌才能访问。
用户每次刷新浏览器,OTP数据库都会关闭,我正在寻找无需用户再次输入密码即可便捷打开容器的方法。
我的拟用方案是利用WebAuthN的id字段存储容器的哈希用户密码,用户每次登录时从中提取该密码。我知道这是一种“投机取巧”的做法,并非WebAuthN的设计用途,但想知道这种做法存在的问题?
以下是我计划实现的代码示例(已测试,可正常运行):
const LOCAL_STORAGE_KEY = "credentialId"; async function storeSensitiveDataToWebauthN(sensitiveString) { let userHandle = new TextEncoder().encode(sensitiveString); let createOptions = { publicKey: { rp: { name: "My local test" }, user: { id: userHandle, name: "example@example.com", displayName: "Example User", }, challenge: new Uint8Array(32), // In practice, should be generated by the server pubKeyCredParams: [{ alg: -7, type: "public-key" }], }, }; const credential = await navigator.credentials.create(createOptions); localStorage.setItem( LOCAL_STORAGE_KEY, btoa(String.fromCharCode.apply(null, new Uint8Array(credential.rawId))) ); } async function retrieveSensitiveDataFromWebauthN() { let credentialId = localStorage.getItem(LOCAL_STORAGE_KEY); // Correctly decode the Base64-encoded credential ID before using it const decodedCredentialId = Uint8Array.from(atob(credentialId), (c) => c.charCodeAt(0) ); let getCredentialDefaultArgs = { publicKey: { challenge: new Uint8Array(32), // Should be securely generated allowCredentials: [{ id: decodedCredentialId, type: "public-key" }], }, }; const assertion = await navigator.credentials.get(getCredentialDefaultArgs); let userHandle = assertion.response.userHandle ? new TextDecoder().decode(assertion.response.userHandle) : null; return userHandle; } export async function testWebAuthN() { const sensitiveString = "USER_HASHED_PASSWORD"; if (localStorage.getItem(LOCAL_STORAGE_KEY) === null) { await storeSensitiveDataToWebauthN(sensitiveString); } const dateRecieved = await retrieveSensitiveDataFromWebauthN(); if (!dateRecieved === sensitiveString) { console.error("Error: WebauthN failed to retrieve the correct data"); } console.log("dateRecieved = ", dateRecieved); }
我非常希望了解将敏感数据存储到user id中是否存在安全问题,或是有其他我忽略的要点:-)
[各位请注意,我知道这是一种取巧方案,我的问题是这种做法是否存在任何问题]
内容的提问来源于stack exchange,提问作者Wazime
相关产品推荐
相关产品推荐

