利用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
- 利用DATABASE VAULT保護敏感資料Database
- 資料加密(對稱加密和非對稱加密)加密
- 【otter】otter安裝
- 敏感資料
- 資料庫同步利器 otter 雙A同步配置資料庫
- 安裝和使用 otter (資料同步利器)
- DES對稱資料加密加密
- 資料加密-國密SM2對資料進行加密加密
- 部署otter實現mysql主備資料同步(上)MySql
- 部署otter實現mysql主備資料同步(下)MySql
- 利用RSA對前後端加密的探索後端加密
- java使用DES加密方式,實現對資料的加密解密Java加密解密
- 前後端資料加密傳輸 RSA非對稱加密後端加密
- 後臺對Json資料加密、解密JSON加密解密
- 程式碼中的敏感資訊加密方案加密
- 利用Data vault對資料倉儲建模
- Oracle對資料進行加密&解密處理Oracle加密解密
- 對稱、非對稱的加密技術是如何對網站資料進行雙重加密?加密網站
- 如何對U盤檔案資料加密,U盤加密方法教程分享加密
- 新駭客攻擊改變戰術目標對準敏感資料(轉)
- Jmeter使用beanshell對資料進行加密傳輸JMeterBean加密
- 資料加密 第四篇:對稱金鑰加密
- iOS中使用RSA對資料進行加密解密iOS加密解密
- 資料加密加密
- 利用 File Monitor 對付隱藏目錄的加密光碟加密
- RAILS中利用YAML檔案完成資料對接AIYAML
- 資料加密 第五篇:非對稱金鑰加密
- 資料庫加密資料庫加密
- iOS - 資料加密iOS加密
- oracle資料加密Oracle加密
- 透明資料加密加密
- Spring Boot: 加密應用配置檔案敏感資訊Spring Boot加密
- 建立一個加密表空間並對錶內資料進行加密的示例加密
- 利用Data Vault對資料倉儲進行建模(二)
- 如何利用Rman對Oracle資料庫進行備份Oracle資料庫
- Android資料加密之Aes加密Android加密
- Android資料加密之Rsa加密Android加密