<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      AES實現財務數據的加密解密存儲

      • 需求背景

      眾所周知,金融行業有各種各樣的財務報表,有些報表涉及到公司財務或經營相關的敏感數據,需要進行加密存儲,只有掌握密鑰的用戶才能看到解密后的數據。注意,這里所說的加密并不是針對整個數據庫或者表全局加密,而是針對表的某些字段進行加密。

       

      • 實現思路

      1、針對某一張報表創建相對應的一張落地表,相關需要加密的字段統一定義為VARCHAR2(1000)。

      2、實現Hibernate監聽器接口,在實體保存之前進行加密,數據Load出來之后進行解密,這樣可以實現加密解密邏輯的統一處理。

      3、對是否需要加密的實體和字段標注對應的注解,將加密解密的實現邏輯轉化為對注解的解析處理。

      4、統一采用AES加密解密算法,放在工具類中實現,加密解密流程(原圖摘自:https://blog.csdn.net/gulang03/article/details/81175854)如下:

       

       5、其他需要處理的場景

           a、數據的保存和查詢采用的是JDBC的處理方式,需要在SQL中統一處理(建議用JdbcTemplate底層統一封裝下),mysql有內置函數,oracle需要自定義函數實現

           b、數據修改時也需要考慮加密的場景

           c、oracle正常情況,用戶不能訪問sys.dbms_crypto,需要DBA授權

       

      •  核心代碼

       1、注冊監聽器事件

      public class HibernateEvent {
      
          @Autowired
          private SessionFactory sessionFactory;
          @Autowired
          private AesListener aesListener;
      
          @PostConstruct
          public void registerListeners() {
              EventListenerRegistry registry = ((SessionFactoryImpl) sessionFactory).getServiceRegistry().getService(
                      EventListenerRegistry.class);
              registry.getEventListenerGroup(EventType.PRE_INSERT).appendListener(aesListener);
              registry.getEventListenerGroup(EventType.POST_LOAD).appendListener(aesListener);
          }
      
      }

      2、監聽器實現

      @Component
      public class AesListener implements PreInsertEventListener, PostLoadEventListener {
          @Override
          public boolean onPreInsert(PreInsertEvent event) {
      
              Class clazz = event.getPersister().getMappedClass();
      
              String[] propertyNames = event.getPersister().getPropertyNames();
      
              EnableEncrypted enableEncrypted = (EnableEncrypted)clazz.getAnnotation(EnableEncrypted.class);
      
              if(enableEncrypted != null){
                  Field[] fields = clazz.getDeclaredFields();
                  if(fields != null){
                      for(Field field : fields){
                          boolean isAccessible = field.isAccessible();
                          if(!isAccessible){
                              field.setAccessible(true);
                          }
                          Encrypted encrypted = field.getAnnotation(Encrypted.class);
                          if(encrypted != null){
                              try {
                                  Object value = field.get(event.getEntity());
      
                                  Class<?> type = field.getType();
                                  String enStr = null;
                                  if(type == String.class){
                                      enStr = AesUtils.aesEncrypt(value.toString());
                                  }else if(type == Double.class){
                                      Double val = (Double)value;
                                      enStr = AesUtils.aesDecrypt(String.valueOf(val));
                                  }
      
                                  if(enStr != null){
                                      field.set(event.getEntity(), enStr);
                                      field.setAccessible(isAccessible);
      
                                      for(int i = 0; i < propertyNames.length; i++){
                                          if(field.getName().equals(propertyNames[i])){
                                              event.getState()[i] = enStr;
                                              break;
                                          }
                                      }
                                  }
                              } catch (IllegalAccessException e) {
                                  e.printStackTrace();
                              }
                          }
                      }
                  }
              }
              return false;
          }
      }

      3、加密解密工具類

      public class AesUtils {
      
          public static String selectSql(String columnName){
              if(StringUtils.isNotEmpty(columnName)){
                  String alias = columnName.contains(".")?columnName.substring(columnName.lastIndexOf(".")+1):columnName;
                  return whereSql(columnName) + " AS "+alias;
              }
              return null;
          }
      
          public static String whereSql(String columnName){
              if(StringUtils.isNotEmpty(columnName)){
                  return "CAST(AES_DECRYPT(UNHEX("+columnName+"), '"+ AesConstants.AES_KEY +"') AS CHAR)";
              }
              return null;
          }
      
          public static String writeSql(String columnValue){
              if(StringUtils.isNotEmpty(columnValue)){
                  return "HEX(AES_ENCRYPT('"+columnValue+"', '"+AesConstants.AES_KEY+"'))";
              }
              return null;
          }
      
          private static String parseByte2HexStr(byte buf[]) {
              StringBuffer sb = new StringBuffer();
              for (int i = 0; i < buf.length; i++) {
                  String hex = Integer.toHexString(buf[i] & 0xFF);
                  if (hex.length() == 1) {
                      hex = '0' + hex;
                  }
                  sb.append(hex.toUpperCase());
              }
              return sb.toString();
          }
      
          private static byte[] parseHexStr2Byte(String hexStr) {
              if (hexStr.length() < 1)
                  return null;
              byte[] result = new byte[hexStr.length()/2];
              for (int i = 0;i< hexStr.length()/2; i++) {
                  int high = Integer.parseInt(hexStr.substring(i*2, i*2+1), 16);
                  int low = Integer.parseInt(hexStr.substring(i*2+1, i*2+2), 16);
                  result[i] = (byte) (high * 16 + low);
              }
              return result;
          }
      
          public static String aesEncrypt(String content) {
              try {
                  SecretKey key = generateMySQLAESKey("ASCII");
                  Cipher cipher = Cipher.getInstance("AES");
                  cipher.init(Cipher.ENCRYPT_MODE, key);
                  byte[] cleartext = content.getBytes("UTF-8");
                  byte[] ciphertextBytes = cipher.doFinal(cleartext);
                  return new String(Hex.encodeHex(ciphertextBytes));
      
              } catch (UnsupportedEncodingException e) {
                  e.printStackTrace();
              } catch (NoSuchAlgorithmException e) {
                  e.printStackTrace();
              } catch (NoSuchPaddingException e) {
                  e.printStackTrace();
              } catch (InvalidKeyException e) {
                  e.printStackTrace();
              } catch (IllegalBlockSizeException e) {
                  e.printStackTrace();
              } catch (BadPaddingException e) {
                  e.printStackTrace();
              }
              return null;
          }
      
          public static String aesDecrypt(String content){
              try {
                  SecretKey key = generateMySQLAESKey("ASCII");
                  Cipher cipher = Cipher.getInstance("AES");
                  cipher.init(Cipher.DECRYPT_MODE, key);
                  byte[] cleartext = new byte[0];
                  try {
                      cleartext = Hex.decodeHex(content.toCharArray());
                  } catch (DecoderException e) {
                      log.error("非法的16進制字符串:" + content, e);
                  }
                  byte[] ciphertextBytes = cipher.doFinal(cleartext);
                  return new String(ciphertextBytes, "UTF-8");
      
              } catch (UnsupportedEncodingException e) {
                  e.printStackTrace();
              } catch (NoSuchAlgorithmException e) {
                  e.printStackTrace();
              } catch (NoSuchPaddingException e) {
                  e.printStackTrace();
              } catch (InvalidKeyException e) {
                  e.printStackTrace();
              } catch (IllegalBlockSizeException e) {
                  e.printStackTrace();
              } catch (BadPaddingException e) {
                  e.printStackTrace();
              }
              return null;
          }
      
          public static SecretKeySpec generateMySQLAESKey(final String encoding) {
              try {
                  final byte[] finalKey = new byte[16];
                  int i = 0;
                  for(byte b : AesConstants.AES_KEY.getBytes(encoding))
                      finalKey[i++%16] ^= b;
                  return new SecretKeySpec(finalKey, "AES");
              } catch(UnsupportedEncodingException e) {
                  throw new RuntimeException(e);
              }
          }
      
      }

       

      posted @ 2020-06-01 22:06  abingtech  閱讀(769)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 久久久久青草线蕉亚洲| 欧美人与性动交α欧美精品| 国产真人性做爰久久网站 | 成人一区二区三区激情视频| 神马久久亚洲一区 二区| 国产午夜A理论毛片| 三级国产三级在线| 福利视频在线一区二区| 色宅男看片午夜大片啪啪| 国产亚洲无线码一区二区| 国产午夜91福利一区二区| 安溪县| 四虎国产精品永久在线看| 国产精品人一区二区三区| 农村熟女大胆露脸自拍| 人人色在线视频播放| 日本在线 | 中文| 黄色一级片一区二区三区| 亚洲精品无码人妻无码| 亚洲 丝袜 另类 校园 欧美| 午夜精品区| 久久99久国产精品66| 欧美老人巨大XXXX做受视频| 中文字幕亚洲综合久久青草| 亚洲人成线无码7777| 久久综合色一综合色88| 午夜毛片不卡免费观看视频| 久久激情影院| 沅陵县| 欧美级特黄aaaaaa片| 干老熟女干老穴干老女人| 欧美福利电影A在线播放| 亚洲国产一区二区三区最新| 中文字幕日韩有码一区| 亚洲欧洲日产国产av无码| 精品无码国产一区二区三区av| 亚洲最大成人免费av| 亚洲中文字幕无码爆乳APP| 吕梁市| 久久精品国产免费观看频道| 亚洲人成亚洲人成在线观看|