跳转到主要内容

API 密钥和密钥的安全管理方法

本文约需 8 分钟阅读

API 密钥和密钥是授予对服务和数据的程序化访问权限的认证信息。泄露的 API 密钥可能导致未授权访问、数据泄露和意外费用。本文介绍 API 密钥泄露的风险以及安全管理的实用方法。

到底该从哪里开始

请按以下优先顺序改善 API 密钥管理。初学者首先在 .gitignore 中添加 .env 文件,将源代码中硬编码的密钥迁移到环境变量。中级者启用 git-secrets 或 GitHub 的密钥扫描功能,引入自动检测泄露的机制。高级者引入 AWS Secrets Manager 或 HashiCorp Vault,设置密钥自动轮换。

API 密钥泄露为何危险

与保护个人账户的密码不同,API 密钥通常授予对整个服务、数据库或云基础设施的广泛访问权限。仅一个 API 密钥的泄露就可能产生严重的漏洞,导致整个系统被入侵。

自动化机器人持续扫描公开仓库,搜索暴露的认证信息。一旦发现密钥,攻击者可在几分钟内利用它进行加密货币挖矿、数据窃取或对其他系统发起攻击。云服务的按量计费模式下,非法使用导致的账单金额可能在短时间内变得巨大。近年来,通过向合法库注入恶意代码的供应链攻击窃取 API 密钥的案例也在增加。

API 密钥泄露的主要原因

在源代码中硬编码

将 API 密钥直接写入源代码是泄露最常见的原因。即使仓库是私有的,密钥也可能通过代码共享、截图或仓库访问权限变更而暴露。一旦密钥被提交到 Git 历史中,即使从代码中删除也会保留在历史记录中,完全清除需要使用 `git filter-branch` 或 BFG Repo-Cleaner 重写历史。

提交 .env 文件

由于 .gitignore 配置遗漏,包含密钥的 .env 文件被提交到仓库的情况也频繁发生。请在项目初期正确配置 .gitignore,确保 .env、.env.local、.env.production 等文件被确实排除。

构建安全的开发环境,API 安全与认证信息管理实践书 (Amazon)可供参考。

客户端暴露

嵌入前端 JavaScript 的 API 密钥,任何人只要查看页面源代码就能看到。拥有写入权限或敏感数据访问权限的密钥绝对不能在客户端代码中使用。暴露的密钥可能成为攻击者进入系统的后门。如有需要,请设计通过后端 API 中继请求。即使是前端使用的公开 API 密钥(如 Google Maps API 密钥),也应设置 HTTP Referer 限制和 API 密钥使用量上限以防止滥用。

API 密钥的安全管理方法

通过环境变量管理

API 密钥应存储在环境变量中而非源代码中,这是基本原则。本地开发使用 .env 文件,生产环境使用部署平台的环境变量设置功能。.env 文件务必添加到 .gitignore,并在仓库中包含 .env.example 等模板文件(仅包含键名不含值),以便团队成员了解所需的环境变量。

利用密钥管理器

生产环境推荐使用 AWS Secrets Manager、HashiCorp Vault、Google Secret Manager 等专用密钥管理服务。这些服务提供存储加密、细粒度访问控制和自动轮换功能。特别是自动轮换通过限制密钥有效期,可以最小化万一泄露时的影响范围。AWS Secrets Manager 每个密钥每月约 0.40 美元的成本,可大幅降低手动管理的风险和运维负担。

定期轮换密钥

定期轮换(更新)API 密钥,可以限制泄露发生时的影响期间。轮换频率根据密钥重要性设定,生产环境重要密钥 90 天以内,开发环境密钥 180 天以内为参考。手动轮换容易导致人为错误,请尽可能自动化。注意轮换时如果立即使旧密钥失效,根据部署时机可能导致服务暂时中断。应设置新旧密钥并行运行期,确认所有系统切换到新密钥后再使旧密钥失效。

最小权限原则

API 密钥仅授予其特定用途所需的最小权限。避免在应用代码中使用主密钥或管理员级别的认证信息。利用 AWS IAM 策略或 Google Cloud IAM 角色实现细粒度的访问控制最小权限原则是 API 密钥管理中最基本的安全原则。

要深入学习权限设计和访问控制的实现模式,IAM 与访问控制设计解说书 (Amazon)很有帮助。

使用 Passtsuku.com 生成强固的 API 密钥

需要生成自定义 API 密钥或密钥时,Passtsuku.com 很有用。它使用密码学安全的随机数生成字符串,可以获得不可预测的密钥。生成 API 密钥时,请将字符数设置为 32 个以上,启用大写字母、小写字母和数字。符号因服务而异可能不被接受,请确认目标服务的规格后再设置。强度计显示 120 位以上的熵即为 API 密钥足够的强度。

需要一次生成多个密钥时,请利用 Passtsuku.com 的批量生成功能。可以高效地为每个服务、每个环境创建不同的密钥。生成的密钥在浏览器内完成处理,不会通过网络发送到外部,可以放心使用。

泄露的检测与应对

利用 git-secrets、truffleHog、GitHub 的密钥扫描功能等工具检测误提交的认证信息。设置 pre-commit 钩子可以在密钥被提交前自动阻止。万一密钥泄露,请立即使密钥失效并发行新密钥。确认泄露的密钥是否被非法访问,检查访问日志也很重要。数据泄露发生时的应对方法也请参考。

现在就能做的事

  1. 确认 .gitignore 中是否包含 .env、.env.local、.env.production,未设置则添加
  2. 搜索源代码中是否有硬编码的 API 密钥,发现后迁移到环境变量
  3. 使用 Passtsuku.com 生成 32 个字符以上的随机字符串,作为自定义 API 密钥或密钥使用
  4. 启用 GitHub 的密钥扫描功能,自动检测泄露
  5. 为生产环境的重要密钥设置 90 天以内的轮换计划

常见问题

如果不小心在源代码中硬编码了 API 密钥该怎么办?
立即使该密钥失效并发行新密钥。由于 Git 历史中仍有记录,需要用 git filter-branch 或 BFG Repo-Cleaner 重写历史。新密钥请通过环境变量管理。
API 密钥应该多久轮换一次?
生产环境重要密钥 90 天以内,开发环境密钥 180 天以内为参考。使用 AWS Secrets Manager 等工具可以设置自动轮换,减少手动管理风险。
如果需要在前端使用 API 密钥该怎么办?
绝对不要在前端使用具有写入权限或敏感数据访问权限的密钥。请设计通过后端 API 中继请求。即使是公开 API 密钥也应设置 HTTP Referer 限制和使用量上限。

这篇文章对您有帮助吗?

相关术语

XHatena