`

RedisTemplate 对存入redis 中的json 字符串加密和解密

 
阅读更多
使用RedisTemplate 对redis操作时,存入的数据为明文时数据容易被盗,我了解决这个问题,我们可以对数据进行加密后再存入redis 中。具体操作如下:


1.启用缓存:
package com.tms.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.tms.bean.system.client.Jackson2JsonRedisSerializerAes;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.lang.reflect.Method;


/**
* Redis 缓存配置
*/
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport{

//    @Bean
//    public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
//        RedisTemplate<String, String> redisTemplate = new RedisTemplate();
//        redisTemplate.setConnectionFactory(redisConnectionFactory);
//        return redisTemplate;
//    }


    @Bean
    public KeyGenerator keyGenerator() {
        return new KeyGenerator() {
            @Override
            public Object generate(Object target, Method
                    method, Object... params) {
                StringBuilder sb = new StringBuilder();
                sb.append(target.getClass().getName());
                sb.append(method.getName());
                for (Object obj : params) {
                    sb.append(obj.toString());
                }
                return sb.toString();
            }
        };
    }


    @Bean
    public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {

        StringRedisTemplate template = new StringRedisTemplate(factory);
//明文显示
  // Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new //Jackson2JsonRedisSerializer(Object.class);
//密文显示
        Jackson2JsonRedisSerializerAes jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializerAes(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);

        template.setValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }

    @Bean
    public CacheManager cacheManager(RedisTemplate redisTemplate) {
        RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
        cacheManager.setDefaultExpiration(60*60*24*60);//设置过期时间 (秒)
        return cacheManager;
    }

}



2.编写加解密类:

package com.tms.bean.system.util;


import org.apache.tomcat.util.codec.binary.Base64;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
* Created by gjp on 2017/10/11.
*/
public class AESUtil {

    private static final String KEY_ALGORITHM = "AES";
    private static final String DEFAULT_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";//默认的加密算法

    /**
     * AES 加密操作
     *
     * @param content 待加密内容
     * @param password 加密密码
     * @return 返回Base64转码后的加密数据
     */
    public static String encrypt(String content, String password) {
        try {
            Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);// 创建密码器

            byte[] byteContent = content.getBytes("utf-8");

            cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(password));// 初始化为加密模式的密码器

            byte[] result = cipher.doFinal(byteContent);// 加密

            return Base64.encodeBase64String(result);//通过Base64转码返回
        } catch (Exception ex) {
            Logger.getLogger(AESUtil.class.getName()).log(Level.SEVERE, null, ex);
        }

        return null;
    }

    /**
     * AES 解密操作
     *
     * @param content
     * @param password
     * @return
     */
    public static String decrypt(String content, String password) {

        try {
            //实例化
            Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);

            //使用密钥初始化,设置为解密模式
            cipher.init(Cipher.DECRYPT_MODE, getSecretKey(password));

            //执行操作
            byte[] result = cipher.doFinal(Base64.decodeBase64(content));

            return new String(result, "utf-8");
        } catch (Exception ex) {
            Logger.getLogger(AESUtil.class.getName()).log(Level.SEVERE, null, ex);
        }

        return null;
    }



    /**
     * AES 加密操作
     *
     * @param byteContent 待加密内容
     * @param password 加密密码
     * @return 加密字符串
     */
    public static byte[] encryptbyte(byte[] byteContent, byte[] password) {
        try {
            Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);// 创建密码器
            String spwd = new String(password);
            cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(spwd));// 初始化为加密模式的密码器
            byte[] result = cipher.doFinal(byteContent);// 加密
            return  result;
        } catch (Exception ex) {
            Logger.getLogger(AESUtil.class.getName()).log(Level.SEVERE, null, ex);
        }

        return null;
    }

    /**
     * AES 解密操作
     *
     * @param byteContent
     * @param password
     * @return 解密字符串
     */
    public static byte[] decryptByte(byte[] byteContent, byte[] password) {

        try {
            //实例化
            Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
            String pwd = new String(password);
            //使用密钥初始化,设置为解密模式
            cipher.init(Cipher.DECRYPT_MODE, getSecretKey(pwd));
            //执行操作
            byte[] result = cipher.doFinal(byteContent);
            return result;
        } catch (Exception ex) {
            Logger.getLogger(AESUtil.class.getName()).log(Level.SEVERE, null, ex);
        }

        return null;
    }

    /**
     * 生成加密秘钥
     *
     * @return
     */
    private static SecretKeySpec getSecretKey(final String password) {
        //返回生成指定算法密钥生成器的 KeyGenerator 对象
        KeyGenerator kg = null;

        try {
            kg = KeyGenerator.getInstance(KEY_ALGORITHM);

            //AES 要求密钥长度为 128
            kg.init(128, new SecureRandom(password.getBytes()));

            //生成一个密钥
            SecretKey secretKey = kg.generateKey();

            return new SecretKeySpec(secretKey.getEncoded(), KEY_ALGORITHM);// 转换为AES专用密钥
        } catch (NoSuchAlgorithmException ex) {
            Logger.getLogger(AESUtil.class.getName()).log(Level.SEVERE, null, ex);
        }

        return null;
    }

    public static void main(String[] args) {
        String s = "789helloWORLD{name:“信息”}";

        System.out.println("s:" + s);

//        String s1 = AESUtil.encrypt(s, "1234");
//        System.out.println("s1:" + s1);
//
//        System.out.println("s2:"+AESUtil.decrypt(s1, "1234"));


    try {
        byte[] pwd = AESUtil.encryptbyte(s.getBytes("UTF-8"), "1234".getBytes("utf-8"));
        System.out.println(new String(Base64.encodeBase64(pwd)));
        byte[] oldPwd = AESUtil.decryptByte(pwd,"1234".getBytes("UTF-8"));
        System.out.println(new String(oldPwd,"UTF-8"));

    }catch (Exception e){
        e.printStackTrace();
    }



    }

}


3.实现RedisSerializer接口:

package com.tms.bean.system.client;

import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.TypeFactory;
import com.tms.bean.system.util.AESUtil;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;
import org.springframework.util.Assert;

import java.nio.charset.Charset;

/**
* Created by gjp on 2017/10/11.
*
*/
public class Jackson2JsonRedisSerializerAes<T> implements RedisSerializer<T> {

    private static final String PWD = "123456789asdfghjkl";

    public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
    private final JavaType javaType;
    private ObjectMapper objectMapper = new ObjectMapper();

    public Jackson2JsonRedisSerializerAes(Class<T> type) {
        this.javaType = this.getJavaType(type);
    }

    public Jackson2JsonRedisSerializerAes(JavaType javaType) {
        this.javaType = javaType;
    }

    public T deserialize(byte[] bytes) throws SerializationException {
        if(null == bytes || bytes.length ==0) {
            return null;
        } else {
            try {
               byte[] result = AESUtil.decryptByte(bytes,PWD.getBytes(DEFAULT_CHARSET));

                return this.objectMapper.readValue(result, 0, bytes.length, this.javaType);
            } catch (Exception var3) {
                throw new SerializationException("Could not read JSON: " + var3.getMessage(), var3);
            }
        }
    }

    public byte[] serialize(Object t) throws SerializationException {
        if(t == null) {
            return new byte[0];
        } else {
            try {
                 byte[] temp = this.objectMapper.writeValueAsBytes(t);

                return AESUtil.encryptbyte(temp,PWD.getBytes(DEFAULT_CHARSET));
                //return this.objectMapper.writeValueAsBytes(t);
            } catch (Exception var3) {
                throw new SerializationException("Could not write JSON: " + var3.getMessage(), var3);
            }
        }
    }

    public void setObjectMapper(ObjectMapper objectMapper) {
        Assert.notNull(objectMapper, "'objectMapper' must not be null");
        this.objectMapper = objectMapper;
    }

    protected JavaType getJavaType(Class<?> clazz) {
        return TypeFactory.defaultInstance().constructType(clazz);
    }
}




没有加密时实现为:




加密后显示:





  • 大小: 17 KB
  • 大小: 21 KB
分享到:
评论

相关推荐

    redisTemplate封装成redisUtils和分布式锁实现

    RedisTemplate是Spring Data Redis模块中的一个核心组件,用于在Java应用中操作Redis数据库。它提供了一种面向对象的方式来执行各种Redis命令,简化了与Redis的数据交互。本篇将深入探讨如何将RedisTemplate封装成...

    redis2json:以JSON格式导出Redis数据

    redis2json 这是一个快速而肮脏的脚本,它将redis转储到RAM中并打印出相应的JSON。用途您可以通过gzip通过管道传输输出并将其发送到文件,以进行快速的非redis数据备份或导出/迁移到另一个系统。 例如: ./redis_to_...

    Java 实现Redis存储复杂json格式数据并返回给前端

    2. **JSON字符串存储**:最简单的方式是将Java对象转换为JSON字符串,然后存储为Redis中的String类型。Fastjson库在这里被用到,其`toJSONString`方法可以将Java对象转化为JSON格式的字符串。获取时,直接返回JSON...

    通过RedisTemplate连接多个Redis过程解析

    "通过RedisTemplate连接多个...本文详细介绍了通过RedisTemplate连接多个Redis数据库的过程,包括配置文件的设置、添加RedisTemplate的Bean、连接多个Redis数据库等内容,对大家的学习或者工作具有一定的参考学习价值。

    Nodejs实现redis数据Json格式的导出

    在本文中,我们将深入探讨如何使用Node.js与Redis数据库交互,并特别关注如何将Redis中的数据导出为JSON格式。Node.js是一种流行的JavaScript运行环境,它允许开发者在服务器端执行JavaScript代码,非常适合构建实时...

    python3实现将json对象存入Redis以及数据的导入导出

    在将 JSON 对象存入 Redis 时,通常会将 JSON 字符串化后再存入,因为 Redis 不直接支持 JSON 数据类型。例如,可以使用 `json.dumps()` 函数将 Python 对象转换为 JSON 字符串,然后使用 `r.lpush()` 或其他 Redis ...

    Redis缓存,泛型集合与json字符串的相互转换实例

    在本文中,我们将深入探讨Redis缓存的使用,以及如何在Java中处理泛型集合和JSON字符串之间的相互转换。这些技术对于构建高效、可扩展的Web应用程序至关重要,尤其是在处理大量数据时,缓存和数据序列化可以显著提高...

    RedisTemplate,解决redis存储乱码问题

    redis的配置类,里面配置了,一个自定义的 RedisTemplate ,用来解决我们存入redis序列化不统一乱码的问题

    Nginx+Lua+Redis+Json

    "Nginx、Lua、Redis 和 Json 的结合应用" Nginx 是一个高性能的 Web 服务器, Lua 是一种轻量级的脚本语言,而 Redis 是一个高性能的 NoSQL 数据库, Json 是一种轻量级的数据交换格式。通过结合使用这些技术,可以...

    Redis中的动态字符串学习教程

    在Redis中,字符串对象是关键数据类型之一,而`sds`被用来实现这些对象,尤其是在存储和处理字符串值时。`sds`不仅用在数据库键值对的字符串值上,还作为内部程序中的`char*`替代品,提供更高级的功能和优化的性能。...

    Redis 4.字符串键(中).flv

    Redis 4.字符串键(中).flv

    redis在grafana的json文件

    redis在grafana的json文件

    RedisTemplate-redis-优雅玩法

    在Java开发环境中,Spring Boot框架提供了一个强大的工具——RedisTemplate,它使得与Redis交互变得更加简单和优雅。本篇文章将深入探讨如何在Spring Boot项目中优雅地使用RedisTemplate,实现对象的自动序列化和反...

    RedisJSON-Redis的JSON数据类型-C/C++开发

    它允许从Redis密钥(文档)存储,更新和获取JSON值。 主RedisJSON RedisJSON是一个Redis模块,它实现ECMA-404 JSON数据交换标准作为本机数据类型。 它允许从Redis密钥(文档)存储,更新和获取JSON值。 主要功能:...

    Redis 5.字符串键(下).flv

    Redis 5.字符串键(下).flv

    Redis 3.字符串键(上).flv

    Redis 3.字符串键(上).flv

    Java如何处理json字符串value多余双引号

    首先,要了解的是JSON的基本结构,它由键值对组成,其中键(key)和字符串值(string value)都必须用双引号包裹。示例中的错误场景是指在JSON字符串的value中出现了非预期的双引号,这有可能是由于数据源的错误或者...

    redis字符串类型_动力节点Java学院整理

    Redis字符串类型是Redis数据库中最基础的数据结构之一,用于存储单个值。在Redis中,字符串类型不仅限于简单的文本,还可以表示整数或其他简单的数据。本文将深入探讨Redis如何存储和处理字符串类型。 首先,Redis...

    redis集群所需要的 json_pure

    redis集群所需要的 json_pure,centos7亲测可用,redis部署见详细博文

Global site tag (gtag.js) - Google Analytics