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

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

有帮助吗?

解决方案

可能不会。

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

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

其他提示

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

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

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

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

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

但是,您到底想实现什么目标?

根据具体情况,通常有多种方法可以实现您的目标,而不仅仅是依靠在用户计算机上保守秘密“秘密”。

比赛到这里已经晚了...

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

更安全的方法是使用经过验证的 PKI 来保护您的 API 调用。然而,如果您的 API 调用很频繁,这会产生明显的性能开销,但对于绝大多数应用程序来说,这不是问题。

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

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

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

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

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

可是等等:我们还没有安全。我们只是阻止了阅读这些消息。

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

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

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

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

所以总而言之,如果这确实是一个令人担忧的问题,那么不要尝试寻找安全存储 API 密钥的方法。相反,更改您的应用程序使用此 API 的方式(自然假设您可以控制双方)。使用 PKI,或者如果 PKI 太慢,则使用 PKI 共享对称混合(目前这已很少成为问题)。这样您就不会存储任何存在安全问题的内容。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top