4

在应用程序中,我使用 Secret Keys 来计算 API 调用的哈希值。在 .NET 应用程序中,使用 Reflector 之类的程序从程序集中提取信息以包含这些键是相当容易的。

混淆程序集是保护这些密钥的好方法吗?

4

4 回答 4

8

可能不是。

研究密码学和 Windows 的内置信息隐藏机制(例如,DPAPI 并将密钥存储在 ACL 限制的注册表项中)。这与您将获得的安全性一样好,您需要与您的应用程序保持在同一系统上。

如果您正在寻找一种方法来阻止坐在机器旁的人获取您的信息,那就忘了它吧。如果某人下定决心,并且可以不受限制地访问不受您控制的计算机,则无法 100% 确定数据在所有情况下都受到保护。如果他们愿意,有决心的人就会去做。

于 2008-08-28T20:14:55.063 回答
1

我不这么认为,因为混淆(至少我理解它)只会弄乱方法名称,使理解代码变得困难(但并非不可能)。这不会更改实际密钥的数据(我猜您已将其存储在某个常量中)。

如果你只是想让它更难看,你可以在明文上运行一个简单的密码(如 ROT-13 或其他东西),这样它至少不会以明文形式存储在代码本身中。但这肯定不会阻止任何坚定的黑客访问您的密钥。更强大的加密方法无济于事,因为您仍然需要在代码中存储 THAT 的密钥,并且没有任何保护措施。

我能想到的唯一真正安全的事情是以某种方式将密钥保留在应用程序之外,然后限制对密钥的访问。例如,您可以将密钥保存在单独的文件中,然后使用操作系统级别的基于用户的限制来保护该文件;那可能会奏效。您可以对数据库连接执行相同的操作(同样,依靠基于用户的访问限制将非授权用户排除在数据库之外)。

我曾想过为我的应用程序执行此操作,但我从未实现过。

于 2008-08-28T20:25:06.850 回答
1

DannySmurf 是正确的,您不能对运行应用程序的人隐藏密钥;如果应用程序可以获取密钥,那么人也可以。

但是,您到底想要完成什么?

取决于它是什么,通常有一些方法可以实现您的目标,而不仅仅是依靠在您的用户机器上保守秘密“秘密”。

于 2008-09-11T21:36:07.887 回答
1

这里比赛迟到了……

将密钥存储在程序集/程序集配置中的方法从根本上说是不安全的。由于确定的用户将有权访问,因此没有可能的铁定方式来存储它。我不在乎您是否使用地球上最好/最昂贵的混淆产品。我不在乎您是否使用 PDAPI 来保护数据(尽管这样更好)。我不在乎您是否使用本地操作系统保护的密钥库(这甚至更好)。没有一个是理想的,因为所有人都遭受相同的核心问题:用户可以访问密钥,并且它们就在那里,几天、几周甚至几个月甚至几年都不会改变。

更安全的方法是使用久经考验的真正 PKI 来保护您的 API 调用。但是,如果您的 API 调用很繁琐,这会带来明显的性能开销,但对于绝大多数应用程序来说,这不是问题。

如果性能是一个问题,您可以在非对称 PKI 上使用 Diffie-Hellman 来建立一个共享秘密对称密钥,以便与 AES 等密码一起使用。在这种情况下,“共享”是指在客户端和服务器之间共享,而不是在所有客户端/用户之间共享。没有硬编码/烘焙键。任何地方。

密钥是暂时的,每次用户运行程序时都会重新生成,或者如果你真的很偏执,它们可能会超时并需要重新处理。

计算出的共享秘密对称密钥本身仅存储在内存中的 SecureString 中。它们很难提取,即使您这样做,它们也只能在很短的时间内使用,并且仅用于特定客户端(即该会话)之间的通信。换句话说,即使有人破解了他们的本地密钥,它们也只会干扰本地通信。他们不能使用这些知识来影响其他用户,这与所有用户通过代码/配置共享的内置密钥不同。

此外,整个密钥本身永远不会通过网络传递。客户端 Alice 和服务器 Bob 独立计算它们。他们为此传递的信息理论上可以被第三方查理截获,允许他独立计算共享密钥。这就是为什么您使用(成本明显更高)非对称 PKI 来保护 Alice 和 Bob 之间的密钥生成。

在这些系统中,密钥生成通常与身份验证以及会话创建相结合。您通过 PKI “登录”并创建“会话”,完成后,客户端和服务器都独立拥有一个对称密钥,可用于该会话中所有后续通信的数量级更快的加密。对于大型服务器,这对于节省解密的计算周期很重要,而不是对所有内容使用 TLS。

但是等等:我们还不安全。我们只是阻止阅读这些消息。

请注意,仍然需要使用消息摘要机制来防止中间人操纵。虽然没有人可以读取正在传输的数据,但没有 MD 就没有任何东西可以阻止他们修改它。因此,您在加密之前对消息进行哈希处理,然后将哈希与消息一起发送。然后,服务器在解密时重新散列有效负载,并验证它是否与作为消息一部分的散列匹配。如果消息在传输过程中被修改,它们不会,并且整个消息被丢弃/忽略。

最后需要防范的机制是重放攻击。此时,您已阻止人们读取您的数据以及修改您的数据,但您并没有阻止他们简单地再次发送数据。如果这对您的应用程序来说是个问题,它的协议必须提供数据,并且客户端和服务器都必须有足够的状态信息来检测重放。这可以像作为加密有效负载一部分的计数器一样简单。请注意,如果您使用诸如 UDP 之类的传输,您可能已经拥有处理重复数据包的机制,因此已经可以处理重放攻击。

显而易见的是,要做到这一点并不容易。因此,除非您绝对不能,否则请使用 PKI。

请注意,这种方法在游戏行业中被大量使用,其中非常希望在每个玩家上花费尽可能少的计算以实现更高的可扩展性,同时提供安全性以防止黑客/窥探。

所以总而言之,如果这确实是一个问题,而不是试图找到一个安全地存储 API 密钥,不要。相反,更改您的应用程序使用此 API 的方式(假设您自然而然地控制了双方)。如果 PKI 太慢,请使用 PKI,或者使用 PKI 共享的对称混合(这在当今很少出现问题)。然后,您将不会存储任何存在安全问题的内容。

于 2017-03-17T21:51:08.813 回答