问题
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.
回答1:
Here is the approach I think I would take:
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); }Make another helper method that can accept a
JTokenand a list of JSONPath expressions. In this method, match each path against the contents of the token usingSelectTokens. 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()))); } } }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
Passwordwherever it occurs andnumberif it occurs insidecredit_card. Expressed as JSONPath, these would be$..Passwordand$..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.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
来源:https://stackoverflow.com/questions/37821298/how-to-mask-sensitive-values-in-json-for-logging-purposes