API 密钥设计探索:多种方法测试对比,最终选定 SHAKE 算法!
个人信息与博客背景作者 Vjaylakshman K 有个人网页包含关于、作品集、博客、愿望清单和简历等链接。距离其上一篇博客已过去很长时间过去几个月工作繁忙没时间写博客。上次写博客时还是 DevOps 工程师如今已成为产品开发人员。此次想探讨 API 密钥因讲解其工作原理的文章少所以将研究所得写成博客分享聚焦于 API 密钥的创建和设计。API 密钥概述API 密钥是无需会话即可通过身份验证和授权来访问 API 的令牌常用于公共 API允许用户直接调用端点并获取响应。作者对其简单定义不满意因好奇心旺盛决定深入探究。API 密钥的格式API 密钥通常按特定方式格式化前缀是额外元数据对识别类型有帮助如 GitHub、Stripe 有各自前缀。示例密钥中接下来是随机十六进制字符串长度不同实现有所不同最后是校验和用于验证密钥有效性。业界常用此格式特殊情况是十六进制字符前缀一部分可能是单个账户唯一十六进制 ID。这些 API 密钥经哈希处理后存储在数据库创建后需复制保存否则无法找回类似密码。有些 API 只存储前几个字符方便区分还可添加权限、记录 API 调用等。开发遇到的难题作者开发基于多租户和分片的系统公共 API 要集成到现有后端工作流程用户数据和 API 密钥哈希值及相关表存储在不同分片中。问题是如何将请求路由到正确的数据库分片之前有会话 cookie 可根据元分片映射表确定账户所属分片于是作者进行研究寻找解决方法。解决方法尝试方法一在元分片中直接将哈希值映射到账户 ID这是默认方法把 API 密钥的哈希值直接映射到账户 ID用约 2000 万条记录测试时读写速度快但作者认为有重复操作开始寻找其他方法。方法二前缀法为每个公司分配唯一 API 密钥前缀创建密钥时十六进制字符串前几个字符是该前缀其余是随机十六进制字符。该前缀存储在元分片中的表中与账户 ID 映射再用 ID 查找分片 ID。此方法性能与第一种相当但索引大小和表的整体内存占用减少。缺点是前缀易被预测哈希冲突可能性增加但可忽略不计作者因个人偏好未采用。方法三对哈希值进行编码作者和 Claude 一起尝试想到用另一种编码算法如 Base64对字符串编码用前几个字符映射账户。先用 Base62 方法做了可行的 POC生成 10 字符编码字符串后尝试 Base70 方法将编码字符串长度减到 8 个字符减小大小并缩短查找时间。但测试基准有缺陷重新测试。测试结果令人困惑深入探究发现两个因素一是 B 树对字符串高效PostgreSQL 中 B 树索引适用于可排序数据SHA 哈希值虽长但查找容易二是 JavaScript 中 BigInt 运算速度慢Base - 62 和 Base - 70 转换通过反复 BigInt 除法完成软件实现的任意精度数学运算在堆上分配多且多次运算导致整体性能差。最终方法SHAKE 哈希算法作者最终选择 SHA3 及其变体 SHAKE 算法它与传统 SHA2 不同像海绵一样吸收文本到 1600 单位块中可按需提取固定大小输出。该方法比之前编码方法好性能与完整 SHA 哈希方法相当但计算成本和索引大小降低采用 Base64url 表示增加了 API 密钥生成可能性。作者决策考虑性能和哈希冲突可能性根据生日悖论估算选择对生成的哈希值进行 10 字符编码。总结与收获通过解决实际问题作者意识到会犯错误和做假设明白如何提高思路清晰度做好 POC 和研究工作。这次经历是宝贵学习机会学到 API 密钥设计、B 树索引对字符串的工作原理、哈希算法工作方式和 BigInt 运算慢。最终有了可行的 API 密钥系统。那么在其他类似系统中是否也能采用这种方法呢
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2522315.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!