在C#应用程序中存储密钥的位置在哪里?

4
有类似的问题:如何管理对称算法中的密钥 在SHA-1哈希中存储秘密密钥的位置? 我的问题相同,但我想以不同的方式提问。 我有一个C#应用程序。 我正在加密一些应用程序中的数据。 为了加密,我使用秘密密钥或密码。 解密需要相同的东西。
在应用程序中存储此秘密密钥或密码的位置/方式是什么? 从反射中查看字符串密码很容易。 我可以使用一些组合来生成密码,但某些聪明的人可以通过一些努力猜测出来。
是否有任何安全的方法来存储或管理应用程序用于加密数据的秘密密码?

我不确定,但也许我们可以使用 app.config 的 appkeys 并对它们进行加密。 - Moons
2个回答

7
我怀疑没有任何可靠的安全方式来存储密钥。最终,您的程序必须访问密钥,黑客可以通过反向工程轻松找出发生了什么,并将该字符串重定向到他们想要的地方。
您最好的选择是:
- 尽可能混淆密钥。这使得访问“秘密密钥”更加困难,但并不能完全防止黑客访问(请参见上文)。不要将其存储为字符串,而是使用一个函数生成它,或者使用种子并通过函数传递以获取秘密字符串。 - 如果您的用例允许,则使用公钥/私钥对。只有在您希望应用程序加密数据、将其发送到服务器并解密它时才有效。在这种情况下,您嵌入公钥到应用程序中(即使黑客发现也没有关系),并将私钥保留给自己或您的服务器。

不完全是BlokeTech的答案,但是确实提供了指导。感谢您的回答。我认为如果加密和解密都在同一台机器上,那么聪明的破解者无论如何都可以破解它。 - Vijay
5
那么你会如何存储私钥? - Anthony Wood
第二个选项(使用公钥/私钥对)仅在数据传输方面有意义,每次通过https发送任何内容时我们都已经在使用它。问题实际上不是如何安全地传输数据,而是如何在用户的计算机上安全存储它(例如,在Chrome中保存密码的方式)。这样其他应用程序/用户就无法窃取它。 - Mike Keskinov

0
如果您将密钥存储为应用程序设置,并加密应用程序设置,那么我认为您是相当安全的。
您可以使用以下代码来加密app.config的部分内容。
using System;
using System.Configuration;

public static class ConfigurationEncryptor {
    [Flags]
    public enum ConfigurationSectionType {
        ConnectionStrings = 1,
        ApplicationSettings = 2
    }

    /// <summary>
    /// Encrypts the given sections in the current configuration.
    /// </summary>
    /// <returns>True is the configuration file was encrypted</returns>
    public static bool Encrypt(ConfigurationSectionType section) {
        bool result = false;

        Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
        if (config == null)
            throw new Exception("Cannot open the configuration file.");

        if (section.HasFlag(ConfigurationSectionType.ConnectionStrings)) {
            result = result || EncryptSection(config, "connectionStrings");
        }

        if (section.HasFlag(ConfigurationSectionType.ApplicationSettings)) {
            result = result || EncryptSection(config, "appSettings");
        }

        return result;
    }

    /// <summary>
    /// Encrypts the specified section.
    /// </summary>
    /// <param name="config">The config.</param>
    /// <param name="section">The section.</param>
    private static bool EncryptSection(Configuration config, string section) {
        ConfigurationSection currentSection = config.GetSection(section);
        if (currentSection == null)
            throw new Exception("Cannot find " + section + " section in configuration file.");
        if (!currentSection.SectionInformation.IsProtected) {
            currentSection.SectionInformation.ProtectSection("DataProtectionConfigurationProvider");
            config.Save();

            // Refresh configuration
            ConfigurationManager.RefreshSection(section);

            return true;
        }
        return false;
    }
}

然后像这样使用它(例如在您的Main()方法中):

ConfigurationEncryptor.Encrypt(
    ConfigurationEncryptor.ConfigurationSectionType.ApplicationSettings |
    ConfigurationEncryptor.ConfigurationSectionType.ConnectionStrings
);

3
欢迎提供更多信息:为什么没有密钥,它是如何工作的,原始配置文件是否被修改,何时运行此程序(每次使用前还是启动前),仅代码回答并不能使问题变得更简单。 - BananaAcid

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接