【问题标题】:How to securely store a PrivateKey in code [duplicate]如何在代码中安全地存储 PrivateKey [重复]
【发布时间】:2014-09-18 09:03:22
【问题描述】:

我正在开发一个软件项目,该项目最终将在不受信任的环境中运行。我需要执行一些辅助加密签名(这意味着这不是保护数据的主要方法),但不希望将密钥留在这样的普通视图中:

private static final String privateKey = "00AABBCC....0123456789";

我可以使用什么方法来合理地保护它?我知道没有什么是完全证明的,但这会在安全墙中增加一层。

为了澄清:我有一个本质上是字符串的东西,我不希望在调试器中或通过反射轻松取出。我知道类文件的反编译实际上可能会使这个问题变得毫无意义,但这是可以接受的风险。

显然,将密钥存储在异地是理想的,但我不能保证可以访问互联网。

【问题讨论】:

  • 请详细说明限制条件以及“不受信任的环境”和“在普通视图中”的含义。
  • 你关心是否有人在 Mac.getInstance() 上设置断点然后跟踪代码直到他们找到你的密钥?
  • kdgregory,我在乎,但我不确定有什么办法。
  • 看到您对我的帖子的回复,我认为唯一的后续是对您的应用程序和部署过程进行更长的描述。也许您可以从外部配置加载密钥。如果不是,那么我会同意 Kevin 的观点,即可能不值得应用任何混淆。

标签: java cryptography obfuscation


【解决方案1】:

在不受信任的环境中保护密钥是不可能的。你可以混淆你的代码,你可以从任意变量创建一个密钥,无论如何。最后,假设您使用标准的javax.crypto 库,您必须调用Mac.getInstance(),稍后您将在该实例上调用init()。想要你的钥匙的人会得到它。

但是,我认为解决方案是将密钥绑定到环境,而不是程序。签名意味着数据来自已知来源,并且自该来源提供以来未被篡改。目前,您正试图说“保证我的程序产生了数据”。相反,将您的要求更改为“保证我的程序的特定用户生成数据”。然后将责任转移给该用户来照顾他/她的密钥。

【讨论】:

  • 我完全同意你的观点和解决方案。不幸的是,部署限制不允许我按照您的描述更改要求。在这种情况下,我希望将攻击抵御到给定的复杂程度。如果对调试器一半熟练的人的抵抗是可能的,那就这样吧。
【解决方案2】:

忘记在代码中隐藏它。它只会使您的软件更难阅读、调试和维护。如果您的软件必须通过安全审核,您也会被钉死。

如果您无法将密钥放入安全存储(安全地存储在磁盘、安全内存或某人头脑中的密码)中,请不要担心其他任何事情。

如果您在 *nix 环境中,将密钥存储在具有 root/root 400 权限的磁盘上可能“足够好”。

在 Windows 上,您可以使用 DPAPI 将数据存储在 Microsoft 的安全内存中。

您还可以使用轻量级 PBE 来加密敏感密钥,并让用户在应用程序启动时输入密码。

【讨论】:

    【解决方案3】:

    那是谁的私钥?私钥应该是私有的,所以分发它是错误的。

    【讨论】:

    • 关键是我生成的...这是一个真正的问题吗?
    • 这是一个反问。这意味着如果代码不归其所在方所有,则使用它是错误的。
    【解决方案4】:

    首先 - 你考虑到这个问题真好!

    是否可以改为生成私钥,与您的证书颁发机构通信并让其签署密钥(以及管理 CRL)?

    作为替代方案,如果要在 Windows 上运行,您可以使用 Crypto API 安全地存储标记为不可导出的私钥。但是,如何安全地分发该密钥可能是另一个挑战。

    【讨论】:

    • 它有什么好的?这似乎让他很痛苦。
    【解决方案5】:

    您能否将私钥分成两部分:将一个存储在您的程序中,然后以交互方式请求后半部分 - 当您的应用启动时?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-28
      • 2020-07-20
      • 1970-01-01
      • 2015-07-18
      • 2018-05-13
      • 2016-04-01
      • 2017-05-15
      • 2011-05-29
      相关资源
      最近更新 更多