FPE(Format Preserving Encryption) 格式保留加密是一種格式保持與明文相同的加密方式,通常用于數據脫敏。
例如對于敏感的數據信息,如電話號碼(13位數字),FPE算法算法加依舊是13位數字,因此這種特性可以不用變更數據庫中字段格式,有利于傳播。
除了這些優點,還具有:
注:此段引用自《大數據時代下的隱私保護(三)》
更詳細的介紹見:
由于JDK(JRE)未提供的FPE實現,我們需要借助BouncyCastle
庫來完成工作,首先當然是引入Hutool:
<dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.7.12</version> </dependency>
再引入BouncyCastle
庫
<dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk15to18</artifactId> <version>1.69</version> </dependency>
//?映射字符表,規定了明文和密文的字符范圍 BasicAlphabetMapper?numberMapper?=?new?BasicAlphabetMapper("0123456789"); //?初始化?aes?密鑰(隨機),長度必須是16bytes、24bytes或32bytes byte[]?keyBytes?=?RandomUtil.randomBytes(16); final?FPE?fpe?=?new?FPE(FPE.FPEMode.FF1,?keyBytes,?numberMapper,? //?Tweak是為了解決因局部加密而導致結果沖突問題,通常情況下將數據的不可變部分作為Tweak,null則使用默認長度全是0的bytes null); String?phone?=?"13534534567"; //?加密 String?encrypt?=?fpe.encrypt(phone); //?解密 String?decrypt?=?fpe.decrypt(encrypt);
//?映射字符表,規定了明文和密文的字符范圍 BasicAlphabetMapper?numberMapper?=?new?BasicAlphabetMapper("0123456789"); //?初始化?aes?密鑰(隨機) byte[]?keyBytes?=?RandomUtil.randomBytes(16); FPE?fpe?=?new?FPE(FPE.FPEMode.FF3_1,?keyBytes,?numberMapper,? ??//?此處FF3規定tweak為56bit(即7bytes) ??new?byte[7]); String?phone?=?"13534534567"; //?加密 String?encrypt?=?fpe.encrypt(phone); //?解密 String?decrypt?=?fpe.decrypt(encrypt);
相比于AES等加密算法,FPE增加BasicAlphabetMapper
,即有限字母的字典表。
Alphabet:有限字母的字典表,并規定了輸出密文的范圍,例如對于手機號碼而言,是十進制純數字格式的,其Alphabet包括字符'0'-'9'。對于MAC地址而言,是十六進制數字格式,其Alphabet應該包括大寫英文字母的'A'-'E'和數字'0'-'9'在內的十六個字母。
注:此段引用自《大數據時代下的隱私保護(三)》
除了FPE,也可以通過掩碼屏蔽方式完成數據脫敏工作,如手機號13912341234 -> 139****1234,不過這種脫敏并不可逆。
掩碼屏蔽同樣可以借助hutool完成:
//?139****1234 DesensitizedUtil.desensitized("13912341234",?DesensitizedUtil.DesensitizedType.MOBILE_PHONE)
兩種方式對比如下:
|