如何避免将身份验证数据置于版本控制中?

How to avoid putting authentication data in version control?

这个问题只是非正式的,因此我无法提供任何形式的 MWE/example/...

我想开发一个 Java 应用程序来与 eBay API 交互。 为此,必须从他们那里获得一个(私人)密钥进行身份验证,以避免单个应用程序干扰正常进程。很明显,将这些密钥放入 Git 存储库并发布存储库是一个坏主意。

另一方面,我想允许其他人贡献and/or使用我的代码用于他们自己的工作(classic 开源方法)。

我想到了以下方法来解决问题:

  1. 将主要代码编写为 LGPL 库,并使用该库和密钥编写一个小应用程序。因此,库可以毫无问题地发布。
  2. 创建一个包含密钥的单独 class;不要将其放入存储库。
  3. 将 VCS 外部(或被其忽略)的文本文件添加到项目中,并在运行时从 .jar 文件中读取它。
  4. 在编译时做一些奇特的事情:在真正的编译器将正确的数据运行到源文件之前以某种方式替换并在之后删除。那就是将编译器包装在 shell 脚本中或为关键文件配置用户定义的编译例程。

前两种方法的好处是从完成的jar文件中重新获得密钥比较复杂(我猜的,如果容易逆向工程,请指正)。缺点是任何其他人都无法编译该程序。情况1,缺少main方法;在情况 2 中,将引用整个 class 但不会出现。

情况 3 是个坏主意,因为如果您有 jar 文件,您可以直接将密钥提取为文本文件并以纯文本格式保存。

在我看来,案例 4 也不是最好的解决方案:在编译时乱搞源代码对我来说非常讨厌。尽管如此,它(据我所知)是此处介绍的最佳解决方案。

你能想到更好的解决方案吗? 此类问题如何正确处理?

编辑:
为了让事情更清楚: 我不担心使用我的应用程序的用户的凭据。 相反,eBay 要求每个使用其 API 的程序都使用密钥对自身进行身份验证。 这样,如果 运行 僵尸或做非法事情(根据许可协议),eBay 可以关闭单个应用程序。

这些密钥(API 的访问密钥)需要应用程序可读(否则我无法通过它们进行身份验证),但这些密钥不得对其他任何人可用。 如果有人拥有密钥 he/she 可以以我的程序的名义发送 API 调用并导致我的密钥被撤销。

将身份验证凭据作为环境变量存储在您的生产实例上。

不要给他们

有一个类似的 question here on security stack exchange 建议通过您自己的 Web 服务代理 API 调用。因此,与其将密钥分发给客户端,不如将其安全地保存在您的服务器上,并要求对客户端进行身份验证。

一旦您将 API 密钥提供给客户端,无论它是编译到您的应用程序中还是在运行时下载,他们都可以检索它。如果用户聪明而坚定,我就不会相信密钥会保密。即使您像 documentation 建议的那样对其进行加密,在某个时间点它也必须未加密并在 HTTP 请求中发送到 eBay。

关于存储密钥的位置,如果您使用自己的服务,请将密钥保存在所有配置管理内容所在的位置并保持加密。您可以有一个单独的私有 git 存储库,其中包含您的服务 ansible 配置。将此存储库中的密钥保存在加密的 ansible 保险库文件中。

给每个用户一个不同的密钥

eBay API 不支持这一点,但如果您能够为每个用户使用不同的密钥,那么至少您知道如果密钥被滥用应该归咎于谁。

API 确实有用户令牌的概念,让您的应用程序代表用户行事。但是,要在每个请求上使用它们 you still have to pass in your app key。所以您仍然面临将开发密钥保存在哪里的问题...