springboot项目,mybatis自定义sql+CompletableFuture,实现根据指定表和字段实现批量分页进行字段加密(更新)

       我们在开发项目的过程中,出于系统安全性的考虑,时常会把一些敏感数据进行加密处理,今天给大家分享一个使用mysql,mybatis-plus,CompletableFuture 实现的批量分页读取并加密表字段的代码逻辑。不废话,直接上代码。

一、首先是controller层

package com.sf.gis.boot.realperson.controller;

import com.sf.gis.boot.realperson.service.EncryptService;
import com.sf.gis.boot.realperson.vo.JsonResponse;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import springfox.documentation.spring.web.json.Json;

import javax.ws.rs.GET;

/**
 * @author 80004819
 * @ClassName:
 * @Description:
 * @date 2020年09月03日 09:21:35
 */
@RestController
@RequestMapping("/encrypt")
@Slf4j
@Api(tags = "空间数据加密")
public class EncryptController {

    @Autowired
    private EncryptService encryptService;


    @GetMapping("/secretByTable")
    @ApiOperation("根据指定的表名和字段进行加密")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "tableName", value = "指定表名(例如:person_statistic )",
                     dataType = "query"),
            @ApiImplicitParam(name = "fields", value = "需要加密字段(多个字段以逗号形式隔开,例如:wkt,geom,shape)",
                    dataType = "query"),
            @ApiImplicitParam(name = "pageSize", value = "分页读取,每次批量加密数据的条数",
                    dataType = "query", defaultValue = "250")
    })
    public JsonResponse secretByTable(@RequestParam(value = "tableName",required = true) String tableName
            , @RequestParam(value = "fields",required = true) String fields, @RequestParam(value = "pageSize", required = true,defaultValue = "100") Integer pageSize) {
        JsonResponse jsonResponse = new JsonResponse();
        try {
            jsonResponse = encryptService.secretByTable(tableName, fields, pageSize);
        } catch (Exception e) {
            log.error("error", e);
            jsonResponse.setData(JsonResponse.STATUS_FAILED, null);
        }
        return jsonResponse;

    }


}

这里没什么好说的。

二、编写service 逻辑层

package com.sf.gis.boot.realperson.service;

import com.sf.gis.boot.realperson.vo.JsonResponse;

import java.util.LinkedHashMap;

/**
 * @author 80004819
 * @ClassName:
 * @Description:
 * @date 2020年09月03日 09:26:58
 */
public interface EncryptService  {

    JsonResponse secretByTable(String tableName, String fields, Integer pageSize);

}
package com.sf.gis.boot.realperson.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sf.gis.boot.realperson.entity.StandardAddress;
import com.sf.gis.boot.realperson.mapper.EncryptMapper;
import com.sf.gis.boot.realperson.mapper.StandardAddressMapper;
import com.sf.gis.boot.realperson.service.EncryptService;
import com.sf.gis.boot.realperson.vo.JsonResponse;
import com.sf.gis.boot.sys.entity.SysDictionary;
import com.sf.gis.boot.sys.service.SysDictionaryService;
import com.sf.gis.boot.utils.SecurtUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StopWatch;
import springfox.documentation.spring.web.json.Json;

import static com.sf.gis.boot.realperson.service.impl.EncryptServiceImpl.EncryptTablesEnum.*;
import static com.sf.gis.boot.realperson.vo.JsonResponse.STATUS_FAILED;
import static com.sf.gis.boot.realperson.vo.JsonResponse.STATUS_SUCCESS;


import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

/**
 * @author 80004819
 * @ClassName:
 * @Description:
 * @date 2020年09月03日 09:27:57
 */
@Service
@Slf4j
public class EncryptServiceImpl implements EncryptService {

    @Autowired
    private EncryptMapper encryptMapper;


    private String key = "";


    @Override
    public JsonResponse secretByTable(String tableName, String fields, Integer pageSize) {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        final JsonResponse jsonResponse = new JsonResponse();
        if (StringUtils.isBlank(tableName)) {
            jsonResponse.setData(JsonResponse.STATUS_FAILED, false, "表明不能为空");
            return jsonResponse;
        }
        if (StringUtils.isBlank(fields)) {
            jsonResponse.setData(JsonResponse.STATUS_FAILED, false, "字段不能为空");
            return jsonResponse;
        }

        fields = StringUtils.deleteWhitespace(fields).replaceAll(",", ",");

        if (AOI.getTableName().equals(tableName)) {
            fields = fields.replaceAll("wkt", "st_astext(wkt) as wkt");
        }
        if (PERSON_STATISTIC.getTableName().equals(tableName)) {
            fields = fields.replaceAll("geom", "st_astext(geom) as geom");
        }

        SysDictionary dictByPathKey = sysDictionaryService.getDictByPathKey("PersonDataEncrypt", "extInfoKey");
        key = dictByPathKey.getDicValue();

        //从第一页开始读取
        Page pageParam = new Page(0, pageSize);
        //拼接查询sql语句
        String id = AOI.getTableName().equals(tableName) ? "aoi_id," : "id,";
        //String orderBy = AOI.getTableName().equals(tableName)?" order by aoi_id asc":" order by id";

        StringBuilder sqlBuilder = new StringBuilder("select " + id);
        sqlBuilder.append(fields).append(" from ").append(tableName);
        //.append(orderBy);

        Page<LinkedHashMap<String, Object>> page = encryptMapper.encryptByTable(pageParam, sqlBuilder.toString());

        List<LinkedHashMap<String, Object>> records = page.getRecords();
        if (!CollectionUtils.isEmpty(records)) {
            //第一页数据进行加密
//          encryptAndUpdate(tableName, records);
            CompletableFuture.runAsync(() -> encryptAndUpdate(tableName, records));
            //获取总记录数,计算总共需要分成多少页进行读取
            int total = (int) page.getTotal();
            int batch = total % pageSize == 0 ? total / pageSize : total / pageSize + 1;
            //从第二页开始读取数据并加密
            for (int i = 1; i <= batch; i++) {
                pageParam.setCurrent(i).setSize(pageSize);
                page = encryptMapper.encryptByTable(pageParam, sqlBuilder.toString());
                List<LinkedHashMap<String, Object>> pageRecords = page.getRecords();
                if (!CollectionUtils.isEmpty(pageRecords)) {
//                  encryptAndUpdate(tableName, pageRecords);
                    CompletableFuture.runAsync(() -> encryptAndUpdate(tableName, pageRecords));
                }
            }
            CompletableFuture.allOf();
            stopWatch.stop();
            log.info("所有任务执行完毕,总耗时{}", stopWatch.getTotalTimeMillis());
            jsonResponse.setData(STATUS_SUCCESS, true, "表字段加密成功");
            return jsonResponse;
        } else {
            jsonResponse.setData(STATUS_SUCCESS, true, "无数据");
            return jsonResponse;
        }
    }


    public static final String POLYGON_pre = "POLYGON((";
    public static final String POLYGON_suf = "))";
    public static final String linestring_pre = "linestring(";
    public static final String linestring_suf = ")";
    public static final String point_pre = "point(";
    public static final String point_suf = ")";
    public static final String MULTIPOLYGON_pre = "MULTIPOLYGON(((";
    public static final String MULTIPOLYGON_suf = ")))";


    @Autowired
    private SysDictionaryService sysDictionaryService;

    public void encryptAndUpdate(String tableName, List<LinkedHashMap<String, Object>> list) {
        List<LinkedHashMap<String, String>> result = list.parallelStream().map(x -> {
            LinkedHashMap<String, String> map = new LinkedHashMap<>(x.size());
            for (Map.Entry<String, Object> entry : x.entrySet()) {
                String k = entry.getKey();
                Object v = entry.getValue();
                if (ObjectUtil.isNotEmpty(v)) {
                    if (!"aoiId".equals(k) && !"id".equals(k)) {
                        //判断v是否是空间数据
                        String vStr = ObjectUtil.toString(v);
                        if (StringUtils.startsWithIgnoreCase(vStr, POLYGON_pre) || StringUtils.startsWithIgnoreCase(vStr, linestring_pre)
                                || StringUtils.startsWithIgnoreCase(vStr, point_pre) || StringUtils.startsWithIgnoreCase(vStr, MULTIPOLYGON_pre)) {
                            vStr = subWktForXY(vStr);
                        }
                        String secretField = SecurtUtil.secret(vStr,key);
                        map.put(k + "_encrypt", secretField);
                    } else {
                        map.put(k, ObjectUtil.toString(v));
                    }
                } else {
                    map.put(k + "_encrypt", null);
                }
            }
            return map;
        }).collect(Collectors.toList());
        //批量更新
        encryptMapper.batchUpdate(tableName, result);

//        if (AOI.getTableName().equals(tableName)) {
//            int flag = encryptMapper.batchUpdateAoi(result);
//            log.info(flag+"");
//        } else if (STANDARD_ADDRESS.getTableName().equals(tableName)) {
//            encryptMapper.batchUpdateStandardAddress(result);
//        } else if (PERSON_STATISTIC.getTableName().equals(tableName)) {
//            encryptMapper.batchUpdatePersonStatistic(result);
//        }
    }


    static enum EncryptTablesEnum {
        AOI("aoi"), STANDARD_ADDRESS("standard_address"), PERSON_STATISTIC("person_statistic");
        private String tableName;

        public String getTableName() {
            return tableName;
        }

        public void setTableName(String tableName) {
            this.tableName = tableName;
        }

        EncryptTablesEnum(String tableName) {
            this.tableName = tableName;
        }
    }


    /**
     * 截取wkt,geom,shape字段中的经纬度并进行转换
     *
     * @return
     */
    public String subWktForXY(String wkt) {
        if (StringUtils.startsWithIgnoreCase(wkt, POLYGON_pre)) {
            wkt = wkt.substring(POLYGON_pre.length(), wkt.length() - POLYGON_suf.length());
        } else if (StringUtils.startsWithIgnoreCase(wkt, linestring_pre)) {
            wkt = wkt.substring(linestring_pre.length(), wkt.length() - linestring_suf.length());
        } else if ( StringUtils.startsWithIgnoreCase(wkt, point_pre)) {
            wkt = wkt.substring(point_pre.length(), wkt.length() - point_suf.length());
        } else if ( StringUtils.startsWithIgnoreCase(wkt, MULTIPOLYGON_pre)) {
            wkt = wkt.substring(MULTIPOLYGON_pre.length(), wkt.length() - MULTIPOLYGON_suf.length());
        }
        //MULTIPOLYGON(((114.317113343627 29.8280205416181,114.318119807265 29.8280165418767,114.318269 29.828105,114.318318 29.82817,114.318345 29.828287,114.318371 29.828547,114.318398 29.828775,114.318436 29.829003,114.318543 29.829343,114.318736 29.829874,114.318754229062 29.8299751927346,114.318786723512 29.8301466508578,114.318602 29.830197,114.318436 29.83026,114.317746 29.830448,114.317572 29.830534,114.317148 29.830823,114.316928 29.83087,114.316714 29.830856,114.316408 29.830809,114.316252 29.830832,114.316134 29.830916,114.315898 29.831917,114.315845614531 29.8320052290616,114.315742192735 29.8320174217962,114.315496 29.831972,114.315078 29.8318988072654,114.314936578204 29.831829036327,114.314866 29.831686,114.314746541877 29.831558,114.314664312815 29.8312961927346,114.314643312815 29.8311128072654,114.314697734611 29.830902,114.314702 29.830767,114.314579 29.830651,114.314471 29.830614,114.314203 29.830623,114.314085 29.830569,114.31401 29.830483,114.313999 29.830372,114.314032 29.830209,114.314155 29.829855,114.314311 29.829762,114.314563 29.829674,114.314708 29.829567,114.31475 29.829436,114.314815867174 29.8289833128797,114.316784820548 29.8290955572526,114.316823689012 29.8284137396182,114.317090062874 29.8284289248265,114.317113343627 29.8280205416181)))
        //114.314719|29.845341;114.314971|29.845512;114.315188|29.845617;
        wkt = wkt.replaceAll(" ", "|").replaceAll(",|,", ";");
        return wkt;

    }

}

 主要的处理逻辑就在这里了,我们首先使用一个spring自带的stopWatch 计时器,用于计算整个方法处理时长,成员变量里面的key值是配置在数据库中字典表的数据加密秘钥,首先我们需要拼接一个自定义的sql,读取到第一页的数据可以从Page对象拿到总记录数,计算需要分多少页进行处理,然后通过for循环进行分页读取数据,读取到的数据使用 CompletableFuture 异步处理加密逻辑,因为数据加密逻辑不要求数据的顺序性,这样可以加快代码的执行。最后调用CompletableFuture.allOf()方法会阻塞主线程。方便计算总的执行时长。这里博主做过测试,2500条数据执行时间是1秒,当然还有优化的余地,表字段加索引,修改每次查询数据的条数,批量更新数据的阀值等。

三、编写mapper层

package com.sf.gis.boot.realperson.mapper;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;

import java.util.LinkedHashMap;
import java.util.List;

/**
 * @author 80004819
 * @ClassName:
 * @Description:
 * @date 2020年09月03日 09:37:19
 */
@Mapper
@Repository
public interface EncryptMapper {


        Page<LinkedHashMap<String,Object>> encryptByTable(@Param("page") Page page, @Param("sql") String sql);

        int batchUpdate(@Param("tableName") String tableName, @Param("list") List<LinkedHashMap<String, String>> list);

        int batchUpdateAoi(@Param("list") List<LinkedHashMap<String, String>> list);

        int batchUpdateStandardAddress(@Param("list") List<LinkedHashMap<String, String>> list);

        int batchUpdatePersonStatistic(@Param("list") List<LinkedHashMap<String, String>> list);
}

mapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.sf.gis.boot.realperson.mapper.EncryptMapper">

    <select id="encryptByTable" resultType="java.util.LinkedHashMap" parameterType="java.lang.String">
           ${sql}
    </select>


    <update id="batchUpdate" parameterType="java.util.List">
        <foreach collection="list" item="item" index="index" separator=";">
            update ${tableName} set
            <foreach collection="item.entrySet()" index="key" item="value" separator=",">
                <if test="key!='aoiId' and key!='id'">
                    ${key} =#{value}
                </if>
            </foreach>
            <where>
            <if test="tableName!='' and tableName!=null and tableName=='aoi'">
                aoi_id = #{item.aoiId}
            </if>
            <if test="tableName!='' and tableName!=null and tableName!='aoi'">
                id = #{item.id}
            </if>
            </where>
        </foreach>
    </update>

    <update id="batchUpdateAoi" parameterType="java.util.List">
        <foreach collection="list" item="item" index="index" separator=";">
            update aoi
            <set>
                <if test="item.containsKey('wkt_encrypt')">
                    wkt_encrypt = #{item.wkt_encrypt},
                </if>
                <if test="item.containsKey('x_encrypt')">
                    x_encrypt = #{item.x_encrypt},
                </if>
                <if test="item.containsKey('y_encrypt')">
                    y_encrypt = #{item.y_encrypt}
                </if>
            </set>
            where aoi_id = #{item.aoiId}

        </foreach>
    </update>

    <update id="batchUpdateStandardAddress">
        <foreach collection="list" item="item" index="index" separator=";">
            update standard_address
            <set>
                <if test="item.containsKey('shape_encrypt')">
                    shape_encrypt = #{item.shape_encrypt},
                </if>
                <if test="item.containsKey('x_encrypt')">
                    x_encrypt = #{item.x_encrypt},
                </if>
                <if test="item.containsKey('y_encrypt')">
                    y_encrypt = #{item.y_encrypt}
                </if>
            </set>
            where id = #{item.id}
        </foreach>
    </update>

    <update id="batchUpdatePersonStatistic">
        <foreach collection="list" item="item" index="index" separator=";">
            update person_statistic
            <set>
                <if test="item.containsKey('geom_encrypt')">
                    geom_encrypt = #{item.geom_encrypt},
                </if>
                <if test="item.containsKey('wkt_encrypt')">
                    wkt_encrypt = #{item.wkt_encrypt},
                </if>
                <if test="item.containsKey('x_encrypt')">
                    x_encrypt = #{item.x_encrypt},
                </if>
                <if test="item.containsKey('y_encrypt')">
                    y_encrypt = #{item.y_encrypt}
                </if>
            </set>
            where id = #{item.id}
        </foreach>
    </update>


</mapper>

这里需要说一下的是,代码才开始使用的是下面三个sql语句,分别针对三个不同的表进行批量数据更新的,由于不具有通用性,改用了第一个 batchUpdate 的sql,根据传入的List<LinkedHashMap<String,String>> 生成的动态sql,注意这里的表名${tableName}和字段名${key},需要使用 $符号,而不是#,不然会报错,博主在项目开发过程中踩到的坑,原因是因为#的话,会自动给解析出来的字段 两边加上单引号,导致sql执行报错。

四、空间数据加密类

package com.sf.gis.boot.utils;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.crypto.symmetric.AES;
import cn.hutool.crypto.symmetric.SymmetricAlgorithm;
import cn.hutool.crypto.symmetric.SymmetricCrypto;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.DigestUtils;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.Security;
import java.util.Date;
import java.util.Objects;

import static java.lang.Integer.parseInt;

public class SecurtUtil {

    public static final String KEY = "82626121-5782-1454-1247-15525212";

    private static final Logger log = LoggerFactory.getLogger(SecurtUtil.class);

    private static final int NUM_EIGHT = 8;


    /**
     * 字符串转化成为16进制字符串
     *
     * @param s
     * @return
     */
    public static String strTo16(String s) {

        StringBuffer str = new StringBuffer();
        for (int i = 0; i < s.length(); i++) {
            int ch = (int) s.charAt(i);
            String s4 = Integer.toHexString(ch);

            str.append(s4);
        }
        return str.toString();
    }

    /**
     * 16进制转换成为string类型字符串
     *
     * @param s
     * @return
     */
    public static String hexStringToString(String s) {
        if (s == null || ("").equals(s)) {
            return null;
        }
        s = s.replace(" ", "");
        byte[] baKeyword = new byte[s.length() / 2];
        for (int i = 0; i < baKeyword.length; i++) {
            try {
                baKeyword[i] = (byte) (0xff & parseInt(s.substring(i * 2, i * 2 + 2), 16));
            } catch (Exception e) {
                log.info(e.getMessage());
            }
        }
        try {
            s = new String(baKeyword, "UTF-8");
            new String();
        } catch (Exception e1) {
            log.info(e1.getMessage());
        }
        return s;
    }

    public static String xor(String value, char[] secrets) {
        byte[] bt = value.getBytes();
        for (int i = 0; i < bt.length; i++) {
            if (secrets.length > i) {
                //通过异或运算进行加密
                bt[i] = (byte) (bt[i] ^ (int) secrets[i]);
            }

        }
        //将加密后的字符串保存到 newresult 变量中
        String newresult = new String(bt, 0, bt.length);
        return newresult;
    }

//    public static String xor (String value){
//        String keyValue = strTo16(key);
//        //获取异或char数组
//        char [] secrets = keyValue.toCharArray();
//        byte[] bt=value.getBytes();
//        for(int i=0;i<bt.length;i++)
//        {
//            if (secrets.length > i){
//                bt[i]=(byte)(bt[i] ^ (int)secrets[i]); //通过异或运算进行加密
//            }
//
//        }
//        String newresult=new String(bt,0,bt.length); //将加密后的字符串保存到 newresult 变量中
//        return newresult;
//    }

    public static String xor(String value, String secrets) {
        byte[] bt = null;
        byte[] btSecrets = null;
        try {
            bt = value.getBytes("utf-8");
            btSecrets = secrets.getBytes("utf-8");
        } catch (UnsupportedEncodingException e) {
            log.info(e.getMessage());
        }
        if (Objects.isNull(bt) || Objects.isNull(btSecrets)) {
            return "";
        }
        for (int i = 0; i < bt.length; i++) {

            if (btSecrets.length > i) {
                bt[i] = (byte) (bt[i] ^ (int) btSecrets[i]);
            }

        }
        //将加密后的字符串保存到 newresult 变量中
        String newresult = null;
        try {
            //new String(bt,"US-ASCII");
            newresult = byteToString(bt);


        } catch (Exception e) {
            log.info(e.getMessage());
        }
        return newresult;
    }

    public static String byteToString(byte[] arr) {

        StringBuilder stringBuilder = new StringBuilder();
        byte[] aArr = arr;
        for (int i = 0; i < aArr.length; i++) {
            String one = getBinaryStrFromByte(aArr[i]);

            if (one.indexOf("1") > -1) {
                //从1开始匹配直到遇到第一个0
                one = one.substring(one.indexOf("1"));
            } else {
                one = "";
            }
            String[] v = one.split("0");
            if (v.length > 0 && one.length() == 8) {
                int bytesLength = v[0].length();
                String tmp = getBinaryStrFromByte(aArr[i]);
                String store = tmp.substring(7 - bytesLength);
                StringBuilder storeBuider = new StringBuilder();
                storeBuider.append(store);
                for (int st = 1; st < bytesLength; st++) {
                    String tmp2 = getBinaryStrFromByte(aArr[st + i]);

                    storeBuider.append(tmp2);
                }

                stringBuilder.append(fromCharCode(parseInt(store, 2)));
                i += bytesLength - 1;
            } else {

                stringBuilder.append(fromCharCode(aArr[i]));
            }
        }

        return stringBuilder.toString();
    }

    public static String fromCharCode(int i) {
        String strValue = "" + (char) i;
        return strValue;
    }

    public static String getBinaryStrFromByte(byte b) {

        StringBuffer result = new StringBuffer();
        byte a = b;
        ;
        for (int i = 0; i < NUM_EIGHT; i++) {
            byte c = a;
            //每移一位如同将10进制数除以2并去掉余数。
            a = (byte) (a >> 1);
            a = (byte) (a << 1);
            if (a == c) {
                result.insert(0, "0");

            } else {

                result.insert(0, "1");
            }
            a = (byte) (a >> 1);
        }
        return result.toString();
    }

    public static String byteArr2HexStr(byte[] arrB) throws Exception {

        int iLen = arrB.length;

        // 每个byte用两个字符才能表示,所以字符串的长度是数组长度的两倍
        StringBuffer sb = new StringBuffer(iLen * 2);

        for (int i = 0; i < iLen; i++) {
            int intTmp = arrB[i];
            // 把负数转换为正数
            while (intTmp < 0) {
                intTmp = intTmp + 256;
            }

            // 小于0F的数需要在前面补0
            if (intTmp < 16) {
                sb.append("0");
            }
            sb.append(Integer.toString(intTmp, 16));
        }
        return sb.toString();
    }

    public static String secret(String value, String keyService) {


        String valueTemp = strTo16(value);
        String keyserviceTemp = strTo16(keyService);
        String secretStr = xor(valueTemp, keyserviceTemp);

        String finalStr = new StringBuilder(secretStr).reverse().toString();
        return finalStr;

    }

    public static String AES128Encrypt(String origin) {

        byte[] encrypted = null;
        try {
            byte[] keyArray = KEY.getBytes("utf-8");
            //设置密钥规范为AES
            SecretKeySpec skeySpec = new SecretKeySpec(keyArray, "AES");
            //"算法/模式/补码方式"
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
            encrypted = cipher.doFinal(origin.getBytes());
        } catch (InvalidKeyException | NoSuchAlgorithmException |
                NoSuchPaddingException | IllegalBlockSizeException | BadPaddingException
                | UnsupportedEncodingException e) {
            log.error(e.getMessage());
            return null;
        }
        //此处使用BASE64做转码功能
        return new BASE64Encoder().encode(encrypted);
    }

    public static String AES128Decrypt(String secret) {

        try {
            //参数类型
            byte[] raw = new byte[0];
            raw = KEY.getBytes("ASCII");
            SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
            //"算法/模式/补码方式"
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, skeySpec);
            byte[] encrypted1 = new BASE64Decoder().decodeBuffer(secret);
            byte[] original = cipher.doFinal(encrypted1);
            String originalString = new String(original);
            return originalString;
        } catch (NoSuchAlgorithmException | NoSuchPaddingException |
                InvalidKeyException |
                IOException | IllegalBlockSizeException | BadPaddingException e) {
            log.error(e.getMessage());
            return null;
        }

    }


    public static void main(String[] args) throws NoSuchAlgorithmException, IOException {
        Date date1 = new Date();
        String extinfo = "MULTIPOLYGON(((114.322460023686 29.8905738218866, 114.322771159932 29.8898436378937, 114.323908416554 29.890187801716, 114.323774306104 29.8905738218866, 114.323913780972 29.8906528860745, 114.323860136792 29.8908296175617, 114.323420254514 29.8908947290833, 114.322460023686 29.8905738218866)))";
        String keyservice = "82626121-5782-1454-1247-617142522121";
        String result = secret(extinfo, keyservice);
        System.out.println(result);

        System.out.println(KEY.length());
        System.out.println(AES128Encrypt(keyservice));
        System.out.println(AES128Decrypt(AES128Encrypt(keyservice)));

        String encode = Base64.encode(result);

        System.out.println(encode);
        // 还原为a
        String decodeStr = Base64.decodeStr(encode);

        System.out.println(decodeStr);

    }
}

最后 加密工具类,没什么好说的。大家觉的赞的话,加关注,记得点赞哈

猜你喜欢

转载自blog.csdn.net/qq_31905135/article/details/108418383
今日推荐