您好,欢迎来到爱go旅游网。
搜索
您的当前位置:首页敏感信息加密处理

敏感信息加密处理

来源:爱go旅游网
敏感信息加密处理

版权声明:本⽂为博主原创⽂章,转载请注明出处,欢迎使劲喷⼀、敏感信息加密处理我们要实现什么

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

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

然后,有时我们为了防⽌被脱库导致的数据泄漏,不得不对⼀些敏感信息(⽐如:⾝份证号、⼿机号)进⾏加密。这样的数据不仅要求加密,还需要在展⽰及其他业务场景下完全显⽰,或者掩码显⽰,这就需要我们对加密的内容进⾏解密。⼆、敏感信息加密处理我做了些什么

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

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

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

2.声明Base类,并实现encrypt和decrypt⽅法,⽅法实现利⽤java反射及⾃定义注解3.所有需要⽤到加密及解密的实体对象,必须继承⾃Base类

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

三、敏感信息加密实现  1.先看效果

    

  注释很清楚,先给对象设置⾝份证号,然后执⾏⾃加密⽅法,返回⾃⼰的引⽤,打印出来加密后该对象的json字符串;执⾏⾃解密⽅法,返回⾃⼰的引⽤,打印出来解密后该对象的json字符串。  

2.设计实现结构

1 crypt 2 |

3 |--annotation

4 | |--DecryptFiled

5 | |--EncryptFiled 6 |--crypt

7 | |--EncryptDecryptInterface 8 |--domain

9 | |--BaseInfo

10 | |--SimpleDomain11 |--utils

12 | |--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 encryptSelf(); public 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 * @return */

public 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 * @return */

public 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 * @return */

public 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; }}

SimpleDomain2.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

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- igat.cn 版权所有

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务