晚来一步......
在程序集/程序集配置文件中存储密钥的方法基本上是不安全的。没有可能的绝对方法可以将其存储为决心的用户将拥有访问权限。我不在乎你使用地球上最好/最昂贵的混淆产品。我不在乎你是否使用PDAPI来保护数据(尽管这更好)。我不在乎你是否使用本地操作系统受保护的密钥库(这甚至更好)。所有这些都不理想,因为它们都存在同样的核心问题:用户可以访问密钥,并且它们在那里,不变地存在着,可能持续几天、几周,甚至几个月和几年。
一个更安全的方法是使用经过验证的PKI来保护您的API调用。但是,如果您的API调用很繁琐,这显然会产生性能开销,但对于绝大多数应用程序而言,这不是问题。
如果性能是一个问题,您可以使用Diffie-Hellman算法通过非对称PKI建立共享秘密对称密钥,以便使用AES等密码进行加密。在这种情况下,“共享”意味着客户端和服务器之间共享,而不是所有客户端/用户。没有硬编码/内置密钥。任何地方都没有。
密钥是短暂的,每次用户运行程序时重新生成,或者如果您真的很偏执,它们可能会超时并需要重新创建。
计算出的共享密钥对本身仅在SecureString中存储在内存中。它们很难被提取,即使你这样做了,它们也只能在短时间内用于与特定客户端(即该会话)之间的通信。换句话说,即使有人黑掉了他们的本地密钥,它们也只能用于干扰本地通信。他们无法使用这些知识来影响其他用户,不像通过代码/配置共享的内置密钥。
此外,整个密钥本身从未通过网络传输。客户端Alice和服务器Bob独立计算它们。为了完成这项工作,他们传递的信息理论上可以被第三方Charlie拦截,允许他独立计算共享密钥。这就是为什么要使用(显著更昂贵的)非对称PKI来保护Alice和Bob之间的密钥生成。
在这些系统中,密钥生成往往与认证和会话创建耦合。您通过PKI“登录”并创建您的“会话”,完成后,客户端和服务器都独立拥有一个对于该会话中所有后续通信都可以使用的对数量级更快的加密的对称密钥。对于高规模服务器,这对于节省解密计算周期非常重要,而不是使用TLS来进行所有通信。
但是,等等:我们还没有完全安全。我们只是防止了读取消息。
请注意,仍然需要使用消息摘要机制来防止中间人操纵。虽然没有人能够读取正在传输的数据,但如果没有消息摘要,就没有任何东西可以防止它们进行修改。因此,在加密之前对消息进行哈希,然后将哈希与消息一起发送。服务器在解密时重新对有效载荷进行哈希,并验证它是否与消息中的哈希匹配。如果消息在传输过程中被修改,则它们不会匹配,整个消息将被丢弃/忽略。
需要保护的最后一个机制是重放攻击。到这个点上,你已经防止了人们读取你的数据和修改你的数据,但你没有防止他们简单地再次发送它。如果这对你的应用程序是一个问题,那么它的协议必须提供数据,并且客户端和服务器必须具有足够的有状态信息来检测重放。这可能是一些简单的东西,如作为加密有效负载的一部分的计数器。请注意,如果您使用的是UDP等传输方式,则可能已经有处理重复数据包的机制,因此已经可以处理重放攻击。
显然,要做好这件事并不容易。因此,除非您绝对不能使用公钥基础设施,否则请使用PKI。
请注意,这种方法在游戏行业中被广泛使用,因为高度希望每个玩家的计算量尽可能少,以实现更高的可扩展性,同时提供防止黑客/窥探的安全性。
因此,总之,如果这确实是一个问题,不要试图找到安全存储API密钥的方法。相反,改变您的应用程序如何使用此API(假设您自然地控制了双方)。使用PKI或使用PKI共享对称混合,如果PKI太慢(这在今天很少是问题)。那么您将不会存储任何安全相关的内容。