当前位置: 移动技术网 > IT编程>开发语言>Java > Java 敏感信息加密处理

Java 敏感信息加密处理

2019年07月22日  | 移动技术网IT编程  | 我要评论

一、敏感信息加密处理我们要实现什么

系统往往需要将用户敏感信息进行加密,不同的敏感信息加密要求不同。

比如,密码的加密,我们往往不需要是可逆的。用户输入密码后,通过系统的加密规则,编码后直接比对加密存储的密码,获得比对结果即可证明用户登录信息合法性。

然后,有时我们为了防止被脱库导致的数据泄漏,不得不对一些敏感信息(比如:身份证号、手机号)进行加密。这样的数据不仅要求加密,还需要在展示及其他业务场景下完全显示,或者掩码显示,这就需要我们对加密的内容进行解密。

二、敏感信息加密处理我做了些什么

近来,项目中为了实现这个需求,做了些简单的设计:

注:考虑到在维护生产数据时方便查询,这里使用aes加密方式,该加密方式同mysql的aes加密结果相同,故可在sql中直接使用hex及aes_encrypt函数进行查询;密盐可保存在配置文件中。

1.使用自定义注解,po的每个类中需要加密及解密的字段可添加该注解

2.声明base类,并实现encrypt和decrypt方法,方法实现利用java反射及自定义注解

3.所有需要用到加密及解密的实体对象,必须继承自base类

4.实体类加密时调用encrypt方法,解密时调用decrypt方法,如此可实现对该对象中敏感数据的加密解密

三、敏感信息加密实现

1.先看效果

注释很清楚,先给对象设置身份证号,然后执行自加密方法,返回自己的引用,打印出来加密后该对象的json字符串;执行自解密方法,返回自己的引用,打印出来解密后该对象的json字符串。

2.设计实现结构

crypt
   |
   |--annotation
   |    |--decryptfiled
   |    |--encryptfiled
   |--crypt
   |    |--encryptdecryptinterface
   |--domain
   |    |--baseinfo
   |    |--simpledomain
   |--utils
   |    |--mysqlutils

2.1先看看注解的实现

/**
 * created by bright on 2017/2/22.
 *
 * @author :
 */
@target(elementtype.field)
@retention(retentionpolicy.runtime)
public @interface encryptfiled {
  string value() default "";
}

自定义注解

两个注解的实现一致,注解名称不同而已,不再贴另外一个注解的代码。

2.2定义自加密、自解密接口

base类实现该接口中的自加密自解密方法

/**
 * created by bright on 2017/2/22.
 *
 * @author :
 */
public interface encryptdecryptinterface {
  public <t> t encryptself();
  public <t> t decryptself();
}

自定义接口

2.3mysqlutils的实现

/**
 * created by bright on 2017/2/22.
 *
 * @author :
 */
@component
public class mysqlutils {
  private static final string encrypttype= "aes";//加密方式
  private static final string encoding = "utf-8";//加密时编码

  private static string mysqlutilskey = "aaa";//加密密盐
  private static mysqlutils mysqlutils;//单例
  private static cipher encryptcipher ;//加密cipher
  private static cipher decryptchipher;//解密chipher
  /**
   * 该方法可用在spring项目中使用配置文件设置密盐,默认值为123
   * @param key
   */
  @value("${mysql.column.crypt.key:123}")
  public void setmysqlutilskey(string key){
    mysqlutils.mysqlutilskey = key;
  }
  /**
   * encryptcipher、decryptchipher初始化
   */
  public static void init(){
    try {
      encryptcipher = cipher.getinstance(encrypttype);
      decryptchipher = cipher.getinstance(encrypttype);
      encryptcipher.init(cipher.encrypt_mode, generatemysqlaeskey(mysqlutilskey, encoding));
      decryptchipher.init(cipher.decrypt_mode, generatemysqlaeskey(mysqlutilskey, encoding));
    } catch (invalidkeyexception e) {
      throw new runtimeexception(e);
    } catch (nosuchalgorithmexception e) {
      throw new runtimeexception(e);
    } catch (nosuchpaddingexception e) {
      throw new runtimeexception(e);
    }
  }
  /**
   * 单例获取方法实现
   * @return
   */
  public synchronized static mysqlutils getinstance(){
    if(mysqlutils == null){
      mysqlutils = new mysqlutils();
      init();
    }
    return mysqlutils;
  }
  /**
   * 加密算法
   * @param encryptstring
   * @return
   */
  public string mysqlaesencrypt(string encryptstring) {
    try{
      return new string(hex.encodehex(encryptcipher.dofinal(encryptstring.getbytes(encoding)))).touppercase();
    } catch (badpaddingexception e) {
      throw new runtimeexception(e);
    } catch (unsupportedencodingexception e) {
      throw new runtimeexception(e);
    } catch (illegalblocksizeexception e) {
      throw new runtimeexception(e);
    }
  }
  /**
   * 解密算法
   * @param decryptstring
   * @return
   */
  public string mysqlaesdecrypt(string decryptstring){
    try {
      return new string(decryptchipher.dofinal(hex.decodehex(decryptstring.tochararray())));
    } catch (decoderexception nspe) {
      throw new runtimeexception(nspe);
    } catch (badpaddingexception nsae) {
      throw new runtimeexception(nsae);
    } catch (illegalblocksizeexception ike) {
      throw new runtimeexception(ike);
    }
  }
  /**
   * 产生mysql-aes_encrypt
   * @param key 加密的密盐
   * @param encoding 编码
   * @return
   */
  public static secretkeyspec generatemysqlaeskey(final string key, final string encoding) {
    try {
      final byte[] finalkey = new byte[16];
      int i = 0;
      for(byte b : key.getbytes(encoding))
        finalkey[i++%16] ^= b;
      return new secretkeyspec(finalkey, "aes");
    } catch(unsupportedencodingexception e) {
      throw new runtimeexception(e);
    }
  }
}

mysqlutils

2.4baseinfo类的实现

/**
 * created by bright on 2017/2/22.
 *
 * @author :
 */
public class baseinfo implements cloneable, encryptdecryptinterface {
  /**
   * 拷贝一个对象,并对新对象进行加密
   * 该方法主要用在日志打印上,可防止原对象被加密而影响程序执行
   * @param <t>
   * @return
   */
  public <t extends baseinfo> t cloneandencrypt() {
    t clonet = null;
    try {
      clonet = (t) this.clone();
    } catch (clonenotsupportedexception e) {
      e.printstacktrace();
      return null;
    }
    if(clonet !=null)
      return clonet.encryptself();
    throw new runtimeexception("拷贝对象异常");
  }
  /**
   * 重写clone方法
   * @return
   * @throws clonenotsupportedexception
   */
  @override
  protected object clone() throws clonenotsupportedexception {
    try {
      return super.clone();
    } catch (clonenotsupportedexception e) {
      e.printstacktrace();
      return null;
    }
  }
  /**
   * 实现自加密
   *
   * @param <t>
   * @return
   */
  public <t> t encryptself() {
    field[] declaredfields = this.getclass().getdeclaredfields();
    try {
      if (declaredfields != null && declaredfields.length > 0) {
        for (field field : declaredfields) {
          if (field.isannotationpresent(encryptfiled.class) && field.gettype().tostring().endswith("string")) {
            field.setaccessible(true);
            string fieldvalue = (string) field.get(this);
            if (stringutils.isnotempty(fieldvalue)) {
              field.set(this, mysqlutils.getinstance().mysqlaesencrypt(fieldvalue));
            }
            field.setaccessible(false);
          }
        }
      }
    } catch (illegalaccessexception e) {
      throw new runtimeexception(e);
    }
    return (t) this;
  }
  /**
   * 实现自解密
   *
   * @param <t>
   * @return
   */
  public <t> t decryptself() {
    field[] declaredfields = this.getclass().getdeclaredfields();
    try {
      if (declaredfields != null && declaredfields.length > 0) {
        for (field field : declaredfields) {
          if (field.isannotationpresent(decryptfiled.class) && field.gettype().tostring().endswith("string")) {
            field.setaccessible(true);
            string fieldvalue = (string)field.get(this);
            if(stringutils.isnotempty(fieldvalue)) {
              field.set(this, mysqlutils.getinstance().mysqlaesdecrypt(fieldvalue));
            }
          }
        }
      }
    } catch (illegalaccessexception e) {
      throw new runtimeexception(e);
    }
    return (t) this;
  }
}

baseinfo

2.5一个简单的对象

/**
 * created by bright on 2017/2/22.
 *
 * @author :
 */
public class simpledomain extends baseinfo{
  @encryptfiled
  @decryptfiled
  private string id;
  public string getid() {
    return id;
  }
  public void setid(string id) {
    this.id = id;
  }
}

simpledomain

2.6来个调用

public class client {
  @test
  public void test(){
    simpledomain sd = new simpledomain();//要进行加密解密的实体类
    sd.setid("6029131988005021537");//注入身份证号
    system.out.println(json.tojsonstring(sd.encryptself()));//执行自加密后输出
    system.out.println(json.tojsonstring(sd.decryptself()));//执行自解密后输出
  }
}

client

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持移动技术网!

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网