Maison >Java >javaDidacticiel >Exemple de partage de code pour le traitement du chiffrement des informations sensibles Java

Exemple de partage de code pour le traitement du chiffrement des informations sensibles Java

黄舟
黄舟original
2017-03-18 10:22:493095parcourir

Cet article présente principalement les connaissances pertinentes sur le traitement du cryptage des informations sensibles Java : 1) Ce que nous voulons implémenter pour le traitement du cryptage des informations sensibles ; 2) Ce que j'ai fait pour le traitement du cryptage des informations sensibles ; 3) Comment implémenter le cryptage des informations sensibles ; . Il a une très bonne valeur de référence. Jetons un coup d'œil avec l'éditeur ci-dessous

1 Que voulons-nous obtenir en cryptant souvent des informations sensibles ? Il faut rendre les utilisateurs sensibles. Les informations sont cryptées et différentes informations sensibles ont des exigences de cryptage différentes.

Par exemple, lors du cryptage de mots de passe, nous n'avons souvent pas besoin d'être réversibles. Une fois que l'utilisateur a saisi le mot de passe, les règles de cryptage du système sont utilisées pour comparer directement le mot de passe crypté et stocké après le codage. L'obtention du résultat de la comparaison peut prouver la légitimité des

informations de connexion de l'utilisateur

.

Ensuite, parfois afin d'éviter les fuites de données causées par la suppression de la base de données, nous devons crypter certaines informations sensibles (telles que le numéro d'identification, le numéro de téléphone portable). Ces données doivent non seulement être cryptées, mais doivent également être entièrement affichées ou masquées lors de l'affichage et d'autres scénarios commerciaux, ce qui nous oblige à décrypter le contenu crypté.

2. Qu'ai-je fait pour crypter les informations sensibles ?

Récemment, afin de répondre à cette exigence du projet, quelques conceptions simples ont été réalisées :

Remarque : Compte tenu de la commodité de la requête lors de la maintenance des données de production, la méthode de cryptage aes est utilisée ici. La méthode de cryptage est la même que le résultat du cryptage aes de

mysql

, vous pouvez donc utiliser directement l'hexadécimal. et les fonctions aes_encrypt en SQL pour les requêtes ; Le sel secret peut être enregistré dans le fichier de configuration.

1. Utilisez des annotations personnalisées. Les champs qui doivent être chiffrés et déchiffrés dans chaque classe du po peuvent être ajoutés avec cette annotation

2. méthodes de décryptage. Implémentation de la méthode Utilisez la réflexion Java et les annotations personnalisées

3. Tous les objets d'entité qui doivent être chiffrés et déchiffrés doivent hériter de la classe Base

4. La classe d'entité est cryptée et appelée lors du décryptage de la méthode, afin que le cryptage et le décryptage des données sensibles dans l'objet puissent être réalisés

3. Implémentation du cryptage des informations sensibles

1. Regardez d'abord l'effet

Notes

C'est très clair, définissez d'abord le numéro d'identification de l'objet, puis exécutez la méthode d'auto-chiffrement, renvoie sa propre référence, imprime le json

string crypté de l'objet, exécute la méthode d'auto-déchiffrement, renvoie ; sa propre référence et imprime la chaîne json déchiffrée de l'objet.

2. Concevoir la structure de mise en œuvre

crypt
   |
   |--annotation
   |    |--DecryptFiled
   |    |--EncryptFiled
   |--crypt
   |    |--EncryptDecryptInterface
   |--domain
   |    |--BaseInfo
   |    |--SimpleDomain
   |--utils
   |    |--MySqlUtils
2.1 Examinons d'abord la mise en œuvre des annotations

L'implémentation des deux annotations est cohérente, les noms des annotations sont juste différents, et le code de l'autre annotation ne sera pas publié.

/**
 * Created by bright on 2017/2/22.
 *
 * @author :
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface EncryptFiled {
  String value() default "";
}

自定义注解

2.2 Définir les interfaces d'auto-chiffrement et d'auto-décryptage

La classe de base implémente la méthode d'auto-chiffrement et d'auto-décryptage dans cette interface

/**
 * Created by bright on 2017/2/22.
 *
 * @author :
 */
public interface EncryptDecryptInterface {
  public <T> T encryptSelf();
  public <T> T decryptSelf();
}

自定义接口
Implémentation de 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
Implémentation de la classe 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 Un objet simple

/**
 * 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 Passer un appel

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn