如何修改JSON字符串中的敏感信息

目录
  • 修改JSON字符串中的敏感信息
    • 项目要求把json字符串里面的敏感信息加密
  • 清除敏感字符串内容
    • 分析
    • 解决思路

修改JSON字符串中的敏感信息

项目要求把json字符串里面的敏感信息加密

比如手机号身份证之类,这就要求遍历json,并且覆盖所有的敏感key,原本以为挺难的,静下心来想了想,代码修修改改大约一个小时搞定了,其实是一个简单的递归,跟遍历一个目录并输出所有文件名一样

废话少说,直接贴代码和测试用例。

package com.ucredit.test;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

/**
 * Created by beibei on 18/1/24.
 */
public class JsonTest {
    public static void main(String[] args) {
        String sa = "{'sa':'saas','sb':['sa','ds','sda'],'sc':{'dsa':'21'}}";
        JSONObject jsonObject = JSON.parseObject(sa);
        System.out.println(changeSensitiveMsg(jsonObject).toJSONString());
    }

    //递归对象
    private static JSONObject changeSensitiveMsg(JSONObject jsonObject) {
        for (String key : jsonObject.keySet()) {
            String json = jsonObject.getString(key);
            if (isObject(json)) {
                jsonObject.put(key, changeSensitiveMsg(JSON.parseObject(json)));
            } else if (isArray(json)) {
                jsonObject.put(key, changeSensitiveMsg(JSON.parseArray(json)));
            } else {
                //这里才是最终覆盖敏感属性的操作
                if (isSensitiveKey(key))
                    jsonObject.put(key, "测试");
            }
        }
        return jsonObject;
    }

    //递归数组
    private static JSONArray changeSensitiveMsg(JSONArray jsonArray) {
        for (int i = 0; i < jsonArray.size(); i++) {
            String value = jsonArray.getString(i);
            if (isArray(value)) {
                jsonArray.set(i, changeSensitiveMsg(jsonArray.getJSONArray(i)));
            } else if (isObject(value)) {
                jsonArray.set(i, changeSensitiveMsg(JSON.parseObject(value)));
            }
        }
        return jsonArray;
    }

    //判断是否是对象,这个方法需要优化,遇到特殊字符相当占时间,可以根据json串首字母直接判断
    private static boolean isObject(String str) {
        try {
            JSON.parseObject(str);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    //判断是否是数组,这个方法需要优化,遇到特殊字符相当占时间,可以根据json串首字母直接判断
    private static boolean isArray(String str) {
        try {
            JSON.parseArray(str);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    //是否是敏感key
    public static boolean isSensitiveKey(String key) {
        return true;
    }
}

清除敏感字符串内容

连接邮箱、短信等服务器信息中密码属于敏感信息,需要在内存中清除。常规做法是前台传递密码明文对应char[],使用完后把数组每个元素修改为0。

但是必须出现String的情况不适用,比如:连接邮箱服务器使用的用户密码;调用rest接口传递的json字符串包含密码明文。

分析

字符串为final类型,运行期间不可改变,涉及常量池,赋值为null并不会回收内存。但是new String不同,可以回收内存。但是JVM回收不及时,要是可以在使用完成后清除char[]内容,也可以做到不改变常量池中的内容。问题转化为如何清理new String内存?

解决思路

String只是一个引用,它的内容是char[] value,value为内部私有变量,不可以访问。

但是java反射可以搞定这件事,代码如下:

char[] chars = new char[] { 'a', 'a', 'a', 'a' };
String valueStr = new String(chars);
System.out.println(valueStr);
Field field = valueStr.getClass().getDeclaredField("value");
field.setAccessible(true);
field.set(valueStr, new char[] { 0, 0, 0, 0 });
field.setAccessible(false);
System.out.println(valueStr);
System.out.println("aaaa");
System.out.println(new String(new char[] { 'a', 'a', 'a', 'a' }));

改变了私有变量为可访问权限,得到value,改变数组的值,然后再把权限设回去。加上打印常量池字符串和new String同样的内容,结果如下:

测试证明,这种方法是可行的,不会改变后面同样内容的字符串内容。通过查看源码,org.codehaus.jackson.map.ObjectMapper.writeValueAsString(Object value) 方法,返回的字符串也是new String,所以也是适用的。经过测试,不会影响其它相同内容的json字符串。

这样,对于json字符串和new String都可以使用这样的方式清除敏感信息内容。但是需要注意的是:如果不是new出来的字符串,一旦修改了,就会影响常量池字符串内容,后果很严重。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • Java 格式化输出JSON字符串的2种实现操作

    1 使用阿里的FastJson 1.1 项目的pom.xml依赖 <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.58</version> </dependency> 1.2 Java示例代码 (1) 导入的包: com.alibaba.fastjson.JSON; import

  • Java 手动解析不带引号的JSON字符串的操作

    1 需求说明 项目中遇到了一批不带引号的类JSON格式的字符串: {Name:Heal,Age:20,Tag:[Coding,Reading]} 需要将其解析成JSON对象, 然后插入到Elasticsearch中, 当作Object类型的对象存储起来. 在对比了阿里的FastJson.Google的Gson, 没找到想要的功能 ( 可能是博主不够仔细, 有了解的童学留言告诉我下呀

  • 复杂JSON字符串转换为Java嵌套对象的实现

    目录 背景 方法 预备工作 构建对象模型 使用jackson 库解析 使用GSON解析 不含列表的嵌套对象 背景 实际开发中,常常需要将比较复杂的 JSON 字符串转换为对应的 Java 对象.这里记录下解决方案. 如下所示,是入侵事件检测得到的 JSON 串: [{"rule_id":"反弹shell","format_output":"进程 pname 反向连接到 %dest_ip%:%dest_port%","

  • Java将Date日期类型字段转换成json字符串的方法

    想必我们在做项目的时候,都会遇到服务端与客户端交互数据.一般情况下我们都会采用json格式或者xml格式,将服务端的数据转换成这两种格式之一. 但是,如果我们将数据转换成json格式的时候,我们也许会遇到Date日期型的数据转换成json格式后,并不是我们想要的格式.下面我们通过简单的demo 来说明这个问题. 我们按照一般json格式生成,会出现以下问题: 采用json:将数据生成json格式,需要导入相应的jar包,如下图: Student.java package com.xbmu.bea

  • Java使用JSON传递字符串注意事项解析

    一.问题由来 项目开发中,由于实际需要将某一个功能模块抽取成了一个单独的服务,其他地方需要调用的时候,通过Spring提供的RestTemplate类发送请求进行调用. 经过测试这种方法完全可行,我和同事都能够正常使用,可是有一次调用一个方法时始终出现问题.调用方的参数可以正常传递,可是被调用方却使用匹 配不上,寻找了很久都没找到原因. 二.问题分析 问题主要在传递的invoType参数上,在被调用方一直匹配不上,两边都是使用switch语句进行匹配,数据类型为String类型,调用方的swit

  • 如何修改JSON字符串中的敏感信息

    目录 修改JSON字符串中的敏感信息 项目要求把json字符串里面的敏感信息加密 清除敏感字符串内容 分析 解决思路 修改JSON字符串中的敏感信息 项目要求把json字符串里面的敏感信息加密 比如手机号身份证之类,这就要求遍历json,并且覆盖所有的敏感key,原本以为挺难的,静下心来想了想,代码修修改改大约一个小时搞定了,其实是一个简单的递归,跟遍历一个目录并输出所有文件名一样 废话少说,直接贴代码和测试用例. package com.ucredit.test; import com.ali

  • 如何修改json字符串中某个key对应的value值

    字符串转json ,下面这种方式会把原有的字符串顺序打乱,所以不采用 JSONObject jsonObject = JSON.parseObject(你的JSON); 要先转为LinkedHashMap,再转json LinkedHashMap<String, Object> json = JSON.parseObject(你的JSON,LinkedHashMap.class,Feature.OrderedField); JSONObject jsonObject=new JSONObjec

  • PHP去掉json字符串中的反斜杠\及去掉双引号前的反斜杠

    通过AJAX传到PHP的json字符串有时候加上反斜杠"\"来转义,PHP处理时需要先去掉反斜杠,然后再json_decode. $str = stripslashes($_POST['json']); $arr = json_decode($str,true); PS:php get抓取json怎样去除双引号前面的反斜杠 你这个不算标准的JSON格式数据,可以先将\"替换成"即可. 再用json_decode()系统函数将其转为json对象,如需转为数组加上第二个

  • Mysql 直接查询存储的Json字符串中的数据

    我们平时使用mysql,出于项目需求,可能需要直接将Java对象或者一个大json,直接存到表中的某个字段中:使用的时候再查出来,反序列化到对象或者一个Map中,方便我们操作: 大多时候,我们可能并不需要所有的数据,只想使用这个对象或者json中的某一个值,来做逻辑判断而已 那我们可以这样做,例如:原来我们需要查出某个字段的数据,然后反序列化成对象再调用其中的一个属性 SELECT content FROM table_name WHERE id = 32; 查询结果:列名:content结果:

  • Java如何从json字符串中获取某个值详解

    目录 Java从json串中获取某个值 使用org.json进行解析 使用com.alibaba.fastjson进行解析 总结 Java从json串中获取某个值 java对象是不能直接传输,只有json对象 转成字符串 可以进行传输 故 传输中都是json进行的 接收到json数据之后java在进行解析转换成为字符串.且json适用于很多语言之间的传输 json本质上就是一个map. 对应有两种json进行解析 首先就是先对json的合法性进行验证 是否可以进行解析 点击这里 进行json解析

  • JS遍历Json字符串中键值对先转成JSON对象再遍历

    1.将Json字符串转换成JSON对象 var t='{"firstName": "cyra", "lastName": "richardson"}'; var obj = eval('(' + t + ')'); 2.遍历读取键值对 for(var str in obj){ alert(str+'='+obj[str]); }

  • 使用Springboot对配置文件中的敏感信息加密

    Springboot对配置文件的敏感信息加密 前言 最近公司对软件的安全问题比较在意,要求对配置文件中的敏感信息如数据库密码等进行加密.但是Springboot是一款高度集成的框架,如果仅仅是简单的对数据库密码进行加密了,由于连接数据库的操作是框架自己完成的,这就会造成不小的麻烦. 经过调研,找到了如下方式还比较方便. 项目配置 该项目用到了jasypt库.原理很简单,通过该库提供的方法进行敏感信息加密,生成密文xxxxx,然后将密文使用ENC()包裹起来. 添加依赖 <!-- jasypt场景

  • Java遍历json字符串取值的实例

    java遍历json字符串,取得相应KV值时,各种麻烦,比如将json中的list取出来转为JSONArray,再将list中的object转化为map,再取值(之前的做法),仙子啊通过阿里的fastjson,可以很方便的直接将str转化为JSONArray,再将里面的object强转为JSONObject,然后再通过obj.getInteger("key")和obj.getString("key")等取值. JSONArray json = (JSONArray)

  • Spring Boot配置内容加密实现敏感信息保护

    在之前的系列教程中,我们已经介绍了非常多关于Spring Boot配置文件中的各种细节用法,比如:参数间的引用.随机数的应用.命令行参数的使用.多环境的配置管理等等. 为什么要加密? 可能很多初学者,对于配置信息的加密并不敏感,因为开始主要接触本地的开发,对于很多安全问题并没有太多的考虑.而现实中,我们的配置文件中,其实包含着大量与安全相关的敏感信息,比如:数据库的账号密码.一些服务的密钥等.这些信息一旦泄露,对于企业的重要数据资产,那是相当危险的. 所以,对于这些配置文件中存在的敏感信息进行加

  • Go如何实现json字符串与各类struct相互转换

    目录 json字符串与各类struct相互转换 简单总结 结构体转换为JSON字符串的一个坑 来看一下这个例子 json字符串与各类struct相互转换 不废话了都在代码中了 package main import ( "fmt" "reflect" "encoding/json" "strings" ) type Class struct { Grade int `json:"grade"` //年级 C

随机推荐