利用otter對敏感資料加密
1、需求
mysql的敏感欄位,在同步到從庫時,利用aes加密儲存在從庫。
2、方法
package com.alibaba.otter; import java.io.UnsupportedEncodingException; import java.util.Arrays; import java.util.Objects; import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import org.apache.commons.codec.binary.Hex; import org.apache.commons.lang.StringUtils; import com.alibaba.otter.node.extend.processor.AbstractEventProcessor; import com.alibaba.otter.shared.etl.model.EventColumn; import com.alibaba.otter.shared.etl.model.EventData; import com.alibaba.otter.shared.etl.model.EventType; public class TransferProcessor extends AbstractEventProcessor { private static final String DEFAULT_KEY = "223081629e274cecaxxxxxx"; //秘鑰 public boolean process(EventData eventData) { String eventType = eventData.getEventType().getValue(); if (eventType.equals(EventType.QUERY.getValue())) { return true; } ColumnInfoEnum[] values = ColumnInfoEnum.values(); for (ColumnInfoEnum cie : values) { EventColumn column = getColumn(eventData, cie.getColumnKey()); if (Objects.nonNull(column)) { if (StringUtils.isNotBlank(column.getColumnValue())) { column.setColumnValue(aes_encrypt(column.getColumnValue(), DEFAULT_KEY)); } } } return true; } /****************************** * 字串轉位元組陣列 開始 ****************************************/ /** * * mysql 加密一直的SecretKeySpec * * @param key * * @return * */ public static SecretKeySpec gener(String key) { try { byte[] finalKey = new byte[16]; int i = 0; for (byte b : key.getBytes("utf-8")) { finalKey[i++ % 16] ^= b; } return new SecretKeySpec(finalKey, "AES"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return null; } public static String aes_encrypt(String password, String strKey) { try { byte[] keyBytes = Arrays.copyOf(strKey.getBytes("ASCII"), 16); // 通用的 // SecretKey key = new SecretKeySpec(keyBytes, "AES"); // 生成和mysql一直的加密資料 SecretKeySpec key = gener(strKey); Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, key); byte[] cleartext = password.getBytes("UTF-8"); byte[] ciphertextBytes = cipher.doFinal(cleartext); return new String(Hex.encodeHexString(ciphertextBytes)); } catch (Exception e) { e.printStackTrace(); } return null; } 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); } } public static String aes_decrypt(String content, String aesKey) { try { SecretKey key = generateMySQLAESKey(aesKey, "ASCII"); Cipher cipher = Cipher.getInstance("AES"); cipher.init(Cipher.DECRYPT_MODE, key); byte[] cleartext = Hex.decodeHex(content.toCharArray()); byte[] ciphertextBytes = cipher.doFinal(cleartext); return new String(ciphertextBytes, "UTF-8"); } catch (Exception e) { e.printStackTrace(); } return null; } /****************************** * 字串轉位元組陣列 結束 ****************************************/ private String replace(String sourceValue, int prefixLength, int subffixLength) { sourceValue = sourceValue.trim(); if (StringUtils.isBlank(sourceValue)) { return ""; } int length = sourceValue.length(); if (length < (prefixLength + subffixLength)) { return ""; } sourceValue = sourceValue.replaceAll("(\\s)", "*"); System.out.println(sourceValue); int placeHolderLenth = length - prefixLength - subffixLength; String pattern = "(\\S{" + (prefixLength) + "})\\S{" + placeHolderLenth + "}(\\S{" + subffixLength + "})"; StringBuilder placeHolder = new StringBuilder("$1"); for (int i = 0; i < placeHolderLenth; i++) { placeHolder.append("*"); } placeHolder.append("$2"); return sourceValue.replaceAll(pattern, placeHolder.toString()); } enum ColumnInfoEnum { FIRST_NAME("first_name",1,0), FULL_NAME("full_name",1,0), LAST_NAME("last_name",1,0); //將要加密的欄位放在這,後面的數字沒啥用 ColumnInfoEnum(String columnKey, int prefixLength, int subffixLength) { this.columnKey = columnKey; this.prefixLength = prefixLength; this.subffixLength = subffixLength; } private String columnKey; private int prefixLength; private int subffixLength; public String getColumnKey() { return columnKey; } public int getPrefixLength() { return prefixLength; } public int getSubffixLength() { return subffixLength; } } }
這樣,資料就可以加密儲存在從庫中了:
可以用mysql的自帶函式解密
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28916011/viewspace-2792209/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 利用otter做mysql資料實時脫敏MySql
- 資料加密(對稱加密和非對稱加密)加密
- 敏感資料
- 安裝和使用 otter (資料同步利器)
- 資料庫同步利器 otter 雙A同步配置資料庫
- 程式碼中的敏感資訊加密方案加密
- SpringBoot配置檔案敏感資訊加密方案Spring Boot加密
- 資料加密-國密SM2對資料進行加密加密
- 部署otter實現mysql主備資料同步(上)MySql
- 部署otter實現mysql主備資料同步(下)MySql
- 後臺對Json資料加密、解密JSON加密解密
- 利用RSA對前後端加密的探索後端加密
- Spring Boot加密應用配置檔案敏感資訊(jasypt)Spring Boot加密
- 前後端資料加密傳輸 RSA非對稱加密後端加密
- 利用Data vault對資料倉儲建模
- 對稱、非對稱的加密技術是如何對網站資料進行雙重加密?加密網站
- 如何對U盤檔案資料加密,U盤加密方法教程分享加密
- 資料加密 第四篇:對稱金鑰加密
- Jmeter使用beanshell對資料進行加密傳輸JMeterBean加密
- 資料加密加密
- 資訊保安:資料加密實戰!對專案中資料使用MD5演算法進行加密加密演算法
- 資料加密 第五篇:非對稱金鑰加密
- 國內AI企業深網視界資料庫未加密,200多萬條敏感個人資訊“裸奔”AI資料庫加密
- 利用Data Vault對資料倉儲進行建模(二)
- 資料庫加密資料庫加密
- aes和sm4對128bit資料加密的速度對比加密
- 利用d3.js對大資料資料進行視覺化分析JS大資料視覺化
- python對介面中的資料進行md5加密Python加密
- 對稱加密與非對稱加密加密
- 利用classfinal-maven-plugin對jar進行加密,防止反編譯MavenPluginJAR加密編譯
- 編碼與加密(對稱加密與非對稱加密)加密
- 2.9.2 透明資料加密加密
- ORACLE資料加密(轉)Oracle加密
- JuiceFS 資料加密原理UI加密
- Oracle透明資料加密Oracle加密
- 資料儲存加密的主流方案對比與難點解析加密
- 敏感資料洩露-基於Pikachu的學習
- 談談保護敏感資料的最佳實踐