【问题标题】:How can I securely embed a static string (key) in C#?如何在 C# 中安全地嵌入静态字符串(键)?
【发布时间】:2012-03-01 07:04:55
【问题描述】:

我正在寻找一种在 WP7 应用程序中安全存储 API 密钥的方法。密钥是一个字符串,目前已硬编码到代码中(见下文)。我知道有反射器程序的人可以很容易地看到这个。有没有更好的方法将此密钥打包为我的应用程序的一部分?资源会更安全吗?

string key = "DSVvjankjnersnkaecjnDFSD44VDS23423423rcsedzcadERVSDRFWESDVTsdt";

(这实际上不是关键;))

提前谢谢你。

【问题讨论】:

  • 您可以将这些类型的数据存储在 .config 文件中

标签: c# .net string windows-phone-7 c#-4.0


【解决方案1】:

看看Safeguard Database Connection Strings and Other Sensitive Settings in Your Code,这是一本好书。您的问题在“隐藏应用程序源代码中的键”部分下。

摘录:

如果您在应用程序中定义密钥,除了混淆程序集外,尽量不要将实际密钥字节存储在源代码中。相反,使用持久性特征实现密钥生成逻辑,例如加密算法、密钥大小、密码短语、初始化向量和盐(参见Encrypt and Decrypt Data Using a Symmetric (Rijndael) Key 的示例)。这将引入额外的间接层,因此无法通过简单地从应用程序二进制文件中转储符号来访问密钥。只要您不更改密钥生成逻辑和密钥特性,就可以保证生成的密钥是相同的。最好不要使用静态字符串作为密钥生成特征,而是动态构建它们。另一个建议是像对待数据存储一样对待程序集,即应用适当的 ACL。只有在其他数据保护技术都不起作用并且您唯一的选择是不加密敏感数据时才使用此选项作为最后的手段。

【讨论】:

  • 您介意总结一下这里的内容吗?这将使答案作为独立的答案更有价值(例如,以防链接失效)。
  • 这种“密钥生成”范式不适用于 OAuth 1 或 OAuth 2 中的客户端密码。
【解决方案2】:

我已经阅读了所有这些答案,我认为没有任何方法可以安全地嵌入它 - 无论你把它放在哪里,或者你如何混淆它。只要它在您的 XAP 中并在应用程序中解码,那么它就始终可以被黑客攻击。

如果您需要以合理的保护程度将密钥发送到 xap 中,那么我认为@maka 的答案是您最好的选择 - 尽可能地混淆它 - 但不要认为这会使您安全 - 即不要为您的移动银行应用程序这样做!

或者,如果您确实需要安全性,则不要只在应用内操作 - 也可以使用网络服务器。例如,如果您正在开发 Facebook 应用程序并且需要以某种方式保护您的 Facebook 密钥,那么您需要将用户从您的应用程序重定向到您服务器上的网页以进行身份​​验证。然后,该网页将需要引导用户完成获取访问令牌的过程 - 然后只需该访问令牌(以及公共 appid)需要返回到您的应用程序。而对于那些需要知道密钥来伴随每次通话的网络服务,恐怕每个通话都可能需要通过您的服务器。

【讨论】:

    【解决方案3】:

    您可以使用ProtectedData 加密Api 密钥,然后在运行时对其进行解密。这是如何在 Windows Phone 中加密数据的好教程:Encryption in Mango

    【讨论】:

    • 我试过了,但事实证明你不能使用 ProtectedData 在一台计算机上加密某些东西并在另一台计算机上解密它。正如您在以下内容中看到的:stackoverflow.com/questions/23124000/…
    【解决方案4】:

    也许您可以事先对其进行加密并将其保存在 app.config 中。并在阅读时使用相同的算法对其进行解密。

    【讨论】:

      【解决方案5】:

      您可以使用DotFuscator 禁用使用反射器的功能。 但是,这将不允许您在不重新编译的情况下更改密钥。

      过去我在其他(基于 web/winform 的)软件中使用过以下方法:

      http://weblogs.asp.net/jgalloway/archive/2008/04/13/encrypting-passwords-in-a-net-app-config-file.aspx

      【讨论】:

        【解决方案6】:

        这可能不是一个答案,但肯定是一个建议:

        将加密密钥存储在数据库中。并将加密的“db密码”存储在app.config中。

        1. 使用两个适当的字符串加密/解密算法,比如说算法 x 和 y。
        2. 在发布之前将加密的 db 密码放入 app.config 中。
        3. 解密 app.config 密码(algo y)以连接数据库以获取新的加密字符串(真实的)。
        4. 如果反射器/等,请关闭连接并使用算法 x 解密新字符串。没有运行。
        5. 使用它。
        6. 释放保存字符串的对象。

        【讨论】:

        • 算法选择(通过反射暴露)不是问题,而是密钥管理。例如,您没有在步骤#3 中说密钥存储在哪里。因此,即使有人实施了您的建议,他们仍然会有与 OP 相同的问题。您将密钥存储在哪里?
        • 将加密密钥存储在数据库中。并将加密的“db 密码”存储在 app.config 中。无论如何,我更新了我的答案。 (如果开发者在自己的应用程序中使用了硬编码的自定义加密算法,然后对其进行混淆,那么通过反射暴露它太难了。)
        • @LostInLib:Conrad 可能指的是解密 app.config 密码所需的密钥。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-01-31
        • 2010-09-22
        • 2018-11-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-06-16
        相关资源
        最近更新 更多