JSON Java 中的 PII 数据屏蔽

JSON PII data masking in Java

我想屏蔽 JSON 的某些元素并打印到日志中。掩码可以通过替换为虚拟数据或删除密钥对来实现。Java 中是否有实用程序来进行掩码?

例如,

给定 JSON:

{
    "key1":"value1",
    "key2":"value2",
    "key3":"value3",
}

单独屏蔽键 2 并打印 JSON:

{
    "key1":"value1",
    "key2":"xxxxxx",
    "key3":"value3",
}

{
    "key1":"value1",
    "key3":"value3",
}

您可以使用 jackson 将 json 转换为地图、处理地图并将地图转换回 json。

例如:

import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;

public void mask() throws IOException {
String jsonString = "{\n" +
            "    \"key1\":\"value1\",\n" +
            "    \"key2\":\"value2\",\n" +
            "    \"key3\":\"value3\"\n" +
            "}";
    Map<String, Object> map;    

    // Convert json to map
    ObjectMapper mapper = new ObjectMapper();
    try {
        TypeReference ref = new TypeReference<Map<String, Object>>() { };
        map = mapper.readValue(jsonString, ref);
    } catch (IOException e) {
        System.out.print("cannot create Map from json" + e.getMessage());
        throw e;
    }

    // Process map
    if(map.containsKey("key2")) {
        map.put("key2","xxxxxxxxx");
    }

    // Convert back map to json
    String jsonResult = "";
    try {
        jsonResult = mapper.writeValueAsString(map);
    } catch (IOException e) {
        System.out.print("cannot create json from Map" + e.getMessage());
    }

    System.out.print(jsonResult);

输入将是 JSON 字符串格式的对象或数组类型。这里的可屏蔽键只能是静态的,否则输入字符串将是动态的。

public final class MaskPIData {

  /**
   * Mask able keywords mentioned here. It should be in LOWER CASE.
   */
  private static final Set<String> MASKABLE_KEYS = new HashSet<>(Arrays.asList(
    "email",
    "emails",
    "phone",
    "pin",
    "password",
    "phonenumber",
    "moneys"));

  private static final String MASKING_VALUE = "****";

  private static final ObjectMapper OBJECTMAPPER =  new ObjectMapper();

  private MaskPIData() {
    super();
  }

  private static boolean isValidSet(Set<String> set) {
    return set != null && !set.isEmpty();
  }

  private static boolean isKnownPrimitiveWrapperModel(Object obj) {
    return obj == null || obj instanceof String || obj instanceof Integer || obj instanceof Long
      || obj instanceof Double;
  }

  @SuppressWarnings("unchecked")
  private static JSONObject maskingForJsonObject(Set<String> maskableKeys, JSONObject input) {
    if (!isValidSet(maskableKeys) || input == null) {
      return input;
    }

    Map<String, Object> inputMap = (Map<String, Object>) input;
    Map<String, Object> caseInsensitiveInputMap = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
    caseInsensitiveInputMap.putAll(inputMap);

    for (Map.Entry<String, Object> entryPair : caseInsensitiveInputMap.entrySet()) {
      if (entryPair.getValue() instanceof JSONArray) {
        JSONArray jsonArr = (JSONArray) caseInsensitiveInputMap.get(entryPair.getKey());
        maskingForArray(maskableKeys, entryPair.getKey(), jsonArr);
        caseInsensitiveInputMap.put(entryPair.getKey(), jsonArr);
      } else if (entryPair.getValue() instanceof JSONObject) {
        JSONObject jsonObj = (JSONObject) caseInsensitiveInputMap.get(entryPair.getKey());
        caseInsensitiveInputMap.put(entryPair.getKey(), maskingForJsonObject(maskableKeys, jsonObj));
      } else if (entryPair.getKey() != null && maskableKeys.contains(entryPair.getKey().toLowerCase())) {
        caseInsensitiveInputMap.put(entryPair.getKey(), MASKING_VALUE);
      }
    }

    return OBJECTMAPPER.convertValue(caseInsensitiveInputMap, JSONObject.class);
  }

  @SuppressWarnings("unchecked")
  private static JSONArray maskingForArray(Set<String> maskableKeys, String key,
    JSONArray jsonArr) {
    JSONArray toRet = jsonArr;
    for (int idx = 0; idx < toRet.size(); idx++) {
      Object obj = toRet.get(idx);
      if (isKnownPrimitiveWrapperModel(obj)) {
        if (key != null && maskableKeys.contains(key.toLowerCase())) {
          toRet.remove(idx);
          toRet.add(idx, MASKING_VALUE);
        }
      } else {
        JSONObject jsonObjFromArray = (JSONObject) toRet.get(idx);
        JSONObject maskedJsonObj = maskingForJsonObject(maskableKeys, jsonObjFromArray);
        toRet.remove(idx);
        toRet.add(idx, maskedJsonObj);
      }
    }
    return toRet;
  }

  public static String doMask(String input) {
    String maskedData = input;
    if (maskedData != null && !maskedData.trim().isEmpty()) {
      try {
        if (new JSONParser().parse(maskedData) instanceof JSONObject) {
          JSONObject maskedOutput = maskingForJsonObject(MASKABLE_KEYS,
            (JSONObject) new JSONParser().parse(maskedData));
          maskedData = OBJECTMAPPER.writeValueAsString(maskedOutput);
        } else if (new JSONParser().parse(maskedData) instanceof JSONArray) {
          JSONArray maskedOutput = maskingForArray(MASKABLE_KEYS, null, (JSONArray) new JSONParser().parse(maskedData));
          maskedData = OBJECTMAPPER.writeValueAsString(maskedOutput);
        }
      } catch (Exception e) {
        // to do - Error while masking data
      }
    }
    return maskedData;
  }

  public static void main(String args[]) {
    String input = "{\"item\":{\"test\":\"test\",\"phone\":\"993244\",\"email\":\"mail@mail.com\"}}";
    System.out.println(doMask(input));
  }