자바 민감 정보 암호 화 처리

9899 단어 자바암호 화
1.민감 한 정보 암호 화 처 리 는 우리 가 무엇 을 실현 해 야 합 니까?
시스템 은 사용자 의 민감 한 정 보 를 암호 화해 야 하 는데 서로 다른 민감 한 정보 암호 화 요구 가 다르다.
예 를 들 어 비밀번호 의 암호 화 는 우 리 는 거 스 를 필요 가 없다.사용자 가 비밀 번 호 를 입력 한 후에 시스템 의 암호 화 규칙 을 통 해 인 코딩 한 후에 암호 화 에 저 장 된 비밀 번 호 를 직접 비교 하고 비교 결 과 를 얻 으 면 사용자 로그 인 정보의 합 법성 을 증명 할 수 있다.
그 다음 에 가끔 우 리 는 탈 라 이브 러 리 로 인 한 데이터 유출 을 방지 하기 위해 민감 한 정보(예 를 들 어 신분증 번호,핸드폰 번호)를 암호 화 해 야 한다.이러한 데 이 터 는 암호 화 를 요구 할 뿐만 아니 라 전시 및 기타 업무 장면 에서 완전히 표시 하거나 마스크 로 표시 해 야 하기 때문에 암호 화 된 내용 을 복호화 해 야 한다.
2.민감 한 정보 암호 화 처리 제 가 무엇 을 했 습 니까?
최근 프로젝트 에서 이 수 요 를 실현 하기 위해 간단 한 설 계 를 했다.
주:생산 데 이 터 를 유지 할 때 조회 하기 편리 함 을 고려 하여 aes 암호 화 방식 을 사용 합 니 다.이 암호 화 방식 은 my sql 의 aes 암호 화 결과 와 같 기 때문에 sql 에서 hex 와 aes 를 직접 사용 할 수 있 습 니 다.encrypt 함수 조회 하기;밀 염 은 설정 파일 에 저장 할 수 있 습 니 다.
1.사용자 정의 주 해 를 사용 합 니 다.po 의 각 클래스 에 암호 화 및 복호화 가 필요 한 필드 에 이 주 해 를 추가 할 수 있 습 니 다.
2.Base 클래스 를 설명 하고 encrypt 와 decrypt 방법 을 실현 하 며 자바 반사 및 사용자 정의 주 해 를 실현 합 니 다.
3.암호 화 및 복호화 에 필요 한 모든 실체 대상 은 Base 클래스 에서 계승 해 야 합 니 다.
4.실체 클래스 암호 화 시 encrypt 방법 을 사용 하고 복호화 시 decrypt 방법 을 사용 하면 이 대상 에 민감 한 데이터 에 대한 암호 화 복호화 를 실현 할 수 있 습 니 다.
3.민감 한 정보 암호 화 실현
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.3 MysqlUtils 의 실현

/**
 * 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.4 BaseInfo 류 의 실현

/**
 * 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
이상 은 본 고의 모든 내용 입 니 다.본 고의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 도움 이 되 기 를 바 랍 니 다.또한 저 희 를 많이 지지 해 주시 기 바 랍 니 다!

좋은 웹페이지 즐겨찾기