Heim >Java >javaLernprogramm >Beispielcode-Freigabe für die Verschlüsselung vertraulicher Java-Informationen

Beispielcode-Freigabe für die Verschlüsselung vertraulicher Java-Informationen

黄舟
黄舟Original
2017-03-18 10:22:493095Durchsuche

In diesem Artikel werden hauptsächlich die relevanten Kenntnisse zur Verschlüsselung vertraulicher Informationen in Java vorgestellt: 1) Was wir für die Verschlüsselung vertraulicher Informationen implementieren möchten; 2) Was ich für die Verschlüsselung vertraulicher Informationen getan habe; Verschlüsselung. Es hat einen sehr guten Referenzwert. Schauen wir es uns mit dem Editor unten an.

Systeme müssen den Benutzern häufig vertrauliche Informationen verschlüsseln, und für verschiedene vertrauliche Informationen gelten unterschiedliche Verschlüsselungsanforderungen.

Zum Beispiel müssen wir bei der Verschlüsselung von Passwörtern oft nicht umkehrbar sein. Nachdem der Benutzer das Passwort eingegeben hat, wird das verschlüsselte und gespeicherte Passwort direkt mit den Verschlüsselungsregeln des Systems verglichen. Durch den Erhalt des Vergleichsergebnisses kann die Legitimität der

Benutzer-Anmeldeinformationen

nachgewiesen werden.

Dann müssen wir manchmal einige vertrauliche Informationen (z. B. ID-Nummer, Mobiltelefonnummer) verschlüsseln, um Datenlecks zu verhindern, die durch das Entfernen aus der Datenbank verursacht werden. Solche Daten müssen nicht nur verschlüsselt werden, sondern auch in Anzeige- und anderen Geschäftsszenarien vollständig angezeigt oder maskiert werden, was erfordert, dass wir den verschlüsselten Inhalt entschlüsseln.

2. Was habe ich getan, um sensible Informationen zu verschlüsseln?

Um diese Anforderung im Projekt zu erfüllen, wurden kürzlich einige einfache Designs erstellt:

Hinweis: In Anbetracht der Bequemlichkeit der Abfrage bei der Pflege von Produktionsdaten wird hier die AES-Verschlüsselungsmethode verwendet. Die Verschlüsselungsmethode ist die gleiche wie das AES-Verschlüsselungsergebnis von

MySQL

, sodass Sie Hex direkt verwenden können und aes_encrypt-Funktionen in SQL zur Abfrage; Der geheime Salt kann in der Konfigurationsdatei gespeichert werden.

1. Verwenden Sie benutzerdefinierte Annotationen, die in jeder Klasse des POs verschlüsselt und entschlüsselt werden müssen.

2 Entschlüsselungsmethoden. Methodenimplementierung Verwenden Sie Java Reflection und benutzerdefinierte Anmerkungen

3 Alle Entitätsobjekte, die verschlüsselt und entschlüsselt werden müssen, müssen von der Basisklasse erben

4 Die Entitätsklasse wird beim Entschlüsseln verschlüsselt und aufgerufen. Sie kann die Verschlüsselung und Entschlüsselung vertraulicher Daten im Objekt realisieren

3. Implementierung der Verschlüsselung vertraulicher Informationen

1. Schauen Sie sich zuerst die Wirkung an

Kommentare

Es ist sehr klar, Legen Sie zuerst die ID-Nummer für das Objekt fest und führen Sie dann die Selbstverschlüsselungsmethode aus. Geben Sie die eigene Referenz zurück. Drucken Sie den verschlüsselten JSON

String des Objekts aus und gibt den entschlüsselten JSON-String des Objekts aus.

2. Design-Implementierungsstruktur

crypt
   |
   |--annotation
   |    |--DecryptFiled
   |    |--EncryptFiled
   |--crypt
   |    |--EncryptDecryptInterface
   |--domain
   |    |--BaseInfo
   |    |--SimpleDomain
   |--utils
   |    |--MySqlUtils
2.1 Schauen wir uns zunächst die Implementierung von Anmerkungen an

Die Implementierung der beiden Anmerkungen ist konsistent, die Anmerkungsnamen sind nur unterschiedlich und der Code der anderen Anmerkung wird nicht veröffentlicht.

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

自定义注解

2.2 Selbstverschlüsselungs- und Selbstentschlüsselungsschnittstellen definieren

Basisklasse implementiert die Selbstverschlüsselungs- und Selbstentschlüsselungsmethode in dieser Schnittstelle

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

自定义接口
Implementierung von 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
Implementierung der 2.4BaseInfo-Klasse

/**
 * 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 Ein einfaches Objekt

/**
 * 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 Einen Anruf tätigen

Das obige ist der detaillierte Inhalt vonBeispielcode-Freigabe für die Verschlüsselung vertraulicher Java-Informationen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn