91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

利用Java如何實現對敏感信息進行加密處理

發布時間:2020-11-12 15:34:55 來源:億速云 閱讀:1979 作者:Leah 欄目:編程語言

今天就跟大家聊聊有關利用Java如何實現對敏感信息進行加密處理,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。

一、敏感信息加密處理我們要實現什么

系統往往需要將用戶敏感信息進行加密,不同的敏感信息加密要求不同。

比如,密碼的加密,我們往往不需要是可逆的。用戶輸入密碼后,通過系統的加密規則,編碼后直接比對加密存儲的密碼,獲得比對結果即可證明用戶登錄信息合法性。

然后,有時我們為了防止被脫庫導致的數據泄漏,不得不對一些敏感信息(比如:身份證號、手機號)進行加密。這樣的數據不僅要求加密,還需要在展示及其他業務場景下完全顯示,或者掩碼顯示,這就需要我們對加密的內容進行解密。

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

近來,項目中為了實現這個需求,做了些簡單的設計:

注:考慮到在維護生產數據時方便查詢,這里使用aes加密方式,該加密方式同mysql的aes加密結果相同,故可在sql中直接使用hex及aes_encrypt函數進行查詢;密鹽可保存在配置文件中。

1.使用自定義注解,po的每個類中需要加密及解密的字段可添加該注解

2.聲明Base類,并實現encrypt和decrypt方法,方法實現利用java反射及自定義注解

3.所有需要用到加密及解密的實體對象,必須繼承自Base類

4.實體類加密時調用encrypt方法,解密時調用decrypt方法,如此可實現對該對象中敏感數據的加密解密

三、敏感信息加密實現

1.先看效果

利用Java如何實現對敏感信息進行加密處理

注釋很清楚,先給對象設置身份證號,然后執行自加密方法,返回自己的引用,打印出來加密后該對象的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

看完上述內容,你們對利用Java如何實現對敏感信息進行加密處理有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注億速云行業資訊頻道,感謝大家的支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

田东县| 凌云县| 顺义区| 渝北区| 正定县| 望都县| 积石山| 仪征市| 濉溪县| 新蔡县| 木兰县| 吴旗县| 砀山县| 丰宁| 怀集县| 保定市| 陆丰市| 景谷| 扶余县| 碌曲县| 宽城| 额尔古纳市| 敦煌市| 宜兰县| 沙湾县| 准格尔旗| 平遥县| 寿阳县| 金塔县| 太白县| 腾冲县| 宾阳县| 安远县| 龙江县| 卓尼县| 美姑县| 安丘市| 邵武市| 斗六市| 武鸣县| 新源县|