问题
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
JToken
and 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
Password
wherever it occurs andnumber
if it occurs insidecredit_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.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