【问题标题】:Add/Read configuration from an encrypted file从加密文件添加/读取配置
【发布时间】:2017-06-07 19:38:39
【问题描述】:

我走上了创建自己的ConfigurationProvider 的道路,它会加密尚未加密的文件,并且还能够解密它。

我现在正在努力想出一种方法,以与 .AddJsonFile() 类似的方式将我的解密 appsettings.json 内容(解密字符串)添加到配置中。

最终,我希望能够在我的Startup.cs 中调用.AddEncryptedJson("appsettings.json"),这将解密文件并添加所有必要的配置。

public class CustomConfigProvider : ConfigurationProvider, IConfigurationSource
{
    private readonly RSA _pubKey;
    private readonly RSA _privKey;
    private readonly string _filePath;

    public CustomConfigProvider(string filePath)
    {
        var cert = new X509Certificate2(Path.Combine(Directory.GetCurrentDirectory(), "certs", "IdentityServer4Auth.pfx"), "test");
        _pubKey = RSACertificateExtensions.GetRSAPublicKey(cert);
        _privKey = RSACertificateExtensions.GetRSAPrivateKey(cert);
        _filePath = filePath;
    }

    public override void Load()
    {
        Data = UnencryptMyConfiguration();
    }

    private IDictionary<string, string> UnencryptMyConfiguration()
    {
        EncryptIfNotEncrypted();

        var configFileBytes = File.ReadAllBytes(_filePath);

        var decryptedData = _privKey.Decrypt(configFileBytes, RSAEncryptionPadding.Pkcs1);
        var jsonString = Encoding.UTF8.GetString(decryptedData);

        jsonString = jsonString.Trim(new char[] { '\uFEFF', '\u200B' });
        dynamic result = JsonConvert.DeserializeObject(jsonString);
        Dictionary<string, string> dictObj = result.ToObject<Dictionary<string, string>>();
        return dictObj;
    }

    private void EncryptIfNotEncrypted()
    {
        var configFileBytes = File.ReadAllBytes(_filePath);

        // Check if encrypted
        try
        {
            _privKey.Decrypt(configFileBytes, RSAEncryptionPadding.Pkcs1);
        }
        catch
        {
            var encryptedData = 
                _pubKey.Encrypt(configFileBytes, RSAEncryptionPadding.Pkcs1);

            using (var fs = new FileStream(_filePath, FileMode.Create, FileAccess.Write))
            {
                fs.Write(encryptedData, 0, encryptedData.Length);
            }
        }
    }
    public IConfigurationProvider Build(IConfigurationBuilder builder)
    {
        return new CustomConfigProvider(_filePath);
    }
}

public static class CustomConfigProviderExtensions
{
    public static IConfigurationBuilder AddEncryptedJson(this IConfigurationBuilder builder, string filePath)
    {
        return builder.Add(new CustomConfigProvider(filePath));
    }
}

【问题讨论】:

    标签: c# configuration asp.net-core


    【解决方案1】:

    您可以通过查看 aspnet/Configuration 存储库中的内部 JsonConfigurationFileParserhere 来解决此问题。 通过在您的项目中创建一个类似的类,您将能够成功解析解密的 JSON 字符串。

    要使用解析器,只需将jsonString 作为Stream 提供给它的Parse() 方法。您的 UnencryptMyConfiguration() 方法将如下所示:

    private IDictionary<string, string> UnencryptMyConfiguration()
    {
        EncryptIfNotEncrypted();
    
        var configFileBytes = File.ReadAllBytes(_filePath);
    
        var decryptedData = _privKey.Decrypt(configFileBytes, RSAEncryptionPadding.Pkcs1);
        var jsonString = Encoding.UTF8.GetString(decryptedData);
    
        //treat the decrypted string as a Stream to let JsonConfigurationFileParser handle it
        using (MemoryStream stream = new MemoryStream())
        {
            var parser = new JsonConfigurationFileParser();
            StreamWriter writer = new StreamWriter(stream);
            writer.Write(jsonString);
            writer.Flush();
            stream.Position = 0;
            return parser.Parse(stream);
        };
    }
    

    【讨论】:

    • 很高兴您提出了这个问题。我实际上最终做到了这一点,尽管该类是内部的,所以我不得不复制代码,而不是仅仅重用它
    猜你喜欢
    • 2012-06-07
    • 2019-09-21
    • 1970-01-01
    • 1970-01-01
    • 2023-03-28
    • 2013-08-23
    • 1970-01-01
    • 2012-01-14
    • 1970-01-01
    相关资源
    最近更新 更多