難以置信(aes加密解密原理及流程)簡述aes的加密和解密過程,AES實現(xiàn)財務數(shù)據(jù)的加密解密存儲,查海拔,
目錄:
1.aes加密解密算法
2.aes加密解密流程圖
3.aes加密在線解密
4.aes加解密算法
5.aes加密舉例
6.aes加密破解難度
7.aes加密解密工具類
8.aes算法加密解密原理
9.aes加密解密速度
10.aes加密詳解
1.aes加密解密算法
需求背景眾所周知,金融行業(yè)有各種各樣的財務報表,有些報表涉及到公司財務或經(jīng)營相關的敏感數(shù)據(jù),需要進行加密存儲,只有掌握密鑰的用戶才能看到解密后的數(shù)據(jù)注意,這里所說的加密并不是針對整個數(shù)據(jù)庫或者表全局加密,而是針對表的某些字段進行加密。
2.aes加密解密流程圖
實現(xiàn)思路1、針對某一張報表創(chuàng)建相對應的一張落地表,相關需要加密的字段統(tǒng)一定義為VARCHAR2粵東地圖(1000)2、實現(xiàn)Hibernate監(jiān)聽器接口,在實體保存之前進行加密,數(shù)據(jù)Load出來之后進行解密,這樣可以實現(xiàn)加密解密邏輯的統(tǒng)一處理。
3.aes加密在線解密
3、對是否需要加密的實體和字段標注對應的注解,將加密解密的實現(xiàn)邏輯轉(zhuǎn)化為對注解的解析處理4、統(tǒng)一采用AES加密解密算法,放在工具類中實現(xiàn),加密解密流程(原圖摘自: https://blog.csdn.net/gulang03/article/details/81175854。
4.aes加解密算法
)如下:
5.aes加密舉例
5、其他需要處理的場景a、數(shù)據(jù)的保存和查詢采用的是JDBC的處理方式,需要在SQL中統(tǒng)一處理(建議用JdbcTemp粵東地圖late底層統(tǒng)一封裝下),mysql有內(nèi)置函數(shù),oracle需要自定義函數(shù)實現(xiàn)b、數(shù)據(jù)修改時也需要考慮加密的場景
6.aes加密破解難度
c、oracle正常情況,用戶不能訪問sys.dbms_crypto,需要DBA授權 核心代碼1、注冊監(jiān)聽器事件publicclassHibernateEvent{ @Autowiredprivate
7.aes加密解密工具類
SessionFactory sessionFactory; @Autowiredprivate AesListener aesListener; @PostConstructpublic
8粵東地圖.aes算法加密解密原理
voidregisterListeners(){ EventListenerRegistry registry = ((SessionFactoryImpl) sessionFactory).getServiceRegistry().getService( EventListenerRegistry
9.aes加密解密速度
.class); registry.getEventListenerGroup(EventType.PRE_INSERT).appendListener(aesListener); regi粵東地圖stry.getEventListenerGroup(EventType.POST_LOAD).appendListener(aesListener); } }
10.aes加密詳解
2、監(jiān)聽器實現(xiàn)@ComponentpublicclassAesListenerimplementsPreInsertEventListener, PostLoadEventListener {@Override
public boolean onPreInsert(PreInsertEvent event) { Class clazz = event.getPersi粵東地圖ster().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.get粵東地圖Entity()); Class type = field.getType(); String enStr =
null; if(type == String.class){ enStr = AesUtils.aesEncrypt(value.toString()); }
elseif(type == Double.class){ Doubleval = (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(); } } } } }
returnfalse; } } 3、加密解密工具類publicclassAesUtils { publicstatic String selectSql(String columnName
){ if(StringUtils.isNotEmpty(columnName)){ 粵東地圖 String alias = columnName.contains("."
)?columnName.substring(columnName.lastIndexOf(".")+1):columnName; return whereSql(columnName) +
" AS "+alias; } returnnull; } publicstatic String whereSql(String columnName
){ if(StringUtils.isNotEmpty(column粵東地圖Name)){ return"CAST(AES_DECRYPT(UNHEX("+columnName+
"), "+ AesConstants.AES_KEY +") AS CHAR)"; } returnnull; } publicstatic String
writeSql(String columnValue){ if(StringUtils.isNotEmpty(columnValue)){ return"HEX(AES_ENCRYPT("
+columnValue+", "+A粵東地圖esConstants.AES_KEY+"))"; } returnnull; } privatestatic 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(); } privatestaticbyte[] parseHexStr2Byte(String hexStr) { if (hexStr.length() <
1) returnnull; byte[] result = newbyte[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; } publicstatic 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(cle粵東地圖artext); returnnew 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(); }
returnnull; } publicstatic String aesDecrypt(String content)粵東地圖{ try { SecretKey key = generateMySQLAESKey(
"ASCII"); Cipher cipher = Cipher.getInstance("AES"); cipher.init(Cipher.DECRYPT_MODE, key);
byte[] cleartext = newbyte[0]; try { cleartext = Hex.decodeHex(content.toCharArray()); }
catch (DecoderExcepti粵東地圖on e) { log.error("非法的16進制字符串:" + content, e); }
byte[] ciphertextBytes = cipher.doFinal(cleartext); returnnew 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.prin粵東地圖tStackTrace(); } returnnull; }
publicstatic SecretKeySpec generateMySQLAESKey(final String encoding) { try { final
byte[] finalKey = newbyte[16]; int i = 0; for(byte b : AesConstants.AES_KEY.getBytes(encoding)) finalKey[i++%
16] ^= b; 粵東地圖 returnnew SecretKeySpec(finalKey, "AES"); } catch(UnsupportedEncodingException e) {
thrownew RuntimeException(e); } } }