Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
646 views
in Technique[技术] by (71.8m points)

json.net - How to mask sensitive values in JSON for logging purposes

I have several similar JSON structures that I want to write into a SQL table for logging purposes. However, some of the fields in the JSON contain sensitive information, which I want to partially mask so the full value is not visible in the log.

Here is an example of one of the JSON structures:

{
  "Vault": 1,
  "Transaction": {
    "gateway": {
      "Login": "Nick",
      "Password": "Password"
    },
    "credit_card": {
      "number": "4111111111111"
    }
  }
}

In this case I'm trying to change the 4111 credit card number so that it appears like 4xxx1111 in the JSON. I am using Newtonsoft and have deserialized the JSON into a JObject, but I am stuck on how to mask the value. I think the clue is something with JToken, but haven't figured it out yet. I'd like to make the solution as generic as possible so that it will work with any JSON structure that I might need to log out.

Any help would be appreciated.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Here is the approach I think I would take:

  1. Make a helper method that can take a string value and obscure it in the manner you require for your log. Maybe something like this, for example:

    public static string Obscure(string s)
    {
        if (string.IsNullOrEmpty(s)) return s;
        int len = s.Length;
        int leftLen = len > 4 ? 1 : 0;
        int rightLen = len > 6 ? Math.Min((len - 6) / 2, 4) : 0;
        return s.Substring(0, leftLen) +
               new string('*', len - leftLen - rightLen) +
               s.Substring(len - rightLen);
    }
    
  2. Make another helper method that can accept a JToken and a list of JSONPath expressions. In this method, match each path against the contents of the token using SelectTokens. For each match found, use the first helper method to replace the sensitive value with an obscured version.

    public static void ObscureMatchingValues(JToken token, IEnumerable<string> jsonPaths)
    {
        foreach (string path in jsonPaths)
        {
            foreach (JToken match in token.SelectTokens(path))
            {
                match.Replace(new JValue(Obscure(match.ToString())));
            }
        }
    }
    
  3. Finally, compile a list of JSONPath expressions for the values that you want to obscure across all the JSON bodies you expect to get. From your example JSON above, I think you would want to obscure Password wherever it occurs and number if it occurs inside credit_card. Expressed as JSONPath, these would be $..Password and $..credit_card.number, respectively. (Keep in mind that JSONPath expressions are case sensitive in Json.Net.) Take this list and put it into a configuration setting somewhere so you can change it easily when you need to.

  4. Now, whenever you want to log out some JSON, just do this:

    JToken token = JToken.Parse(json);
    string[] jsonPaths = YourConfigSettings.GetJsonPathsToObscure();
    ObscureMatchingValues(token, jsonPaths);
    YourLogger.Log(token.ToString(Formatting.None));
    

Demo fiddle: https://dotnetfiddle.net/dGPyJF


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...