0

I've been looking for solutions for storing my encrypted connection information in the Appsettings.json, and decrypting it using a ConfigProvider extension. I'm going down this route as I should be able to reuse it on all my production applications. Secrets and Azure Key vault don't seem to be what I'm looking for or have an option on using.

I'm basing it off of this for right now

My json file looks similar to this

{
  "ConnectionStrings": {
    "SerilogConnection": "encryptedConnection",
    "OracleConnection": "encryptedConnection"
  }
}

I'm having a hard time figuring out how to load my json into this dictionary object with the decrypted keys and the returning it in the configuration builder...

private IDictionary<string, string> UnencryptMyConfiguration()
        { 
            // how do parse json this and decrypt?
            // var jObj = JObject.Parse(json);
            // var innerJObj = JObject.FromObject(jObj["ConnectionStrings"]);
            // use decryption method here?
            var configValues = new Dictionary<string, string>
            {
                {"key1", "unencryptedValue1"},
                {"key2", "unencryptedValue2"}
            };

            return configValues;
        }

Does the builder take care of this for me with this?

    var configuration = new ConfigurationBuilder()
        .AddJsonFile($"appsettings.{_currentEnv}.json", optional: true)
        .AddJsonFile("appsettings.json")
        .AddEncryptedProvider() // <-- here?
        .AddEnvironmentVariables()
        .Build();

Here's my decryption method which I have working in a separate project:

public string DecryptData(string data)
{
    string path = @"c:\temp\PrivateKey.txt";
    var privateKey = System.IO.File.ReadAllText(path);

    var bytesCypherText = Convert.FromBase64String(data);

    var csp = new RSACryptoServiceProvider();
    var sr = new System.IO.StringReader(privateKey);
    var xs = new System.Xml.Serialization.XmlSerializer(typeof(RSAParameters));
    var privKey = (RSAParameters)xs.Deserialize(sr);
    csp.ImportParameters(privKey);

    var bytesPlainTextData = csp.Decrypt(bytesCypherText, false);

    var plainTextData = System.Text.Encoding.Unicode.GetString(bytesPlainTextData);
    return plainTextData;
}

I've looked at a ton of resources, read this a bunch, but nothing seems to be really what I'm looking for. Any pointers or suggestions welcome, am I going down the wrong road?

Seth Walz
  • 3
  • 3
  • You can create a custom provider, based on the existing `JsonConfigurationProvider`. All you have to do is call `base.Load(stream);` At this point, you have loaded all the config, encrypted. Now it's just a matter of either going through all of them and calling your decrypt function. Another way: Register a custom class for your config section, and implemnet the decrypt on each `get` accessor. – jpgrassi Mar 12 '19 at 21:22
  • But what I don't like of all these approaches is that it starts from the premise that all my settings are encrypted, which can be very much be false. For instance, I might have a settings called `MyApiSettings` and inside I might have `Secret` and `ClientId`. I only encrypt the secret, so only that one should go through decryption process. – jpgrassi Mar 12 '19 at 21:31
  • @jpgrassi Thanks for the response, I actually did end up doing the decryption the other way that you stated here. Registering a custom class for my config section, and implementing the decrypt on each `get` accessor. It may require a bit more change in each project, but it seemed to be the most reasonable way to achieve what I was looking for. – Seth Walz Mar 20 '19 at 15:40
  • Ah great. You could post here, as others might be interested in knowing how you did it :). Cheers. – jpgrassi Mar 20 '19 at 19:45

0 Answers0