使用Hutool在Java中实现FPE(Format Preserving Encryption)格式保留加密算法
FPE介绍 FPE(Format Preserving Encryption) 格式保留加密是一种格式保持与明文相同的加密方式,通常用于数据脱敏。 例如对于敏感的数据信息,如电话号码(13位数字),FPE算法算法加依旧是13位数字,因此这种特性可以不用变更数据库中字段格式,有利于传播。 除了这些优点,还具有: 数据长度不变。加密前长度是N,加密后长度仍然是N 数据类型不变,加密前是数字类型,加密后仍然是数字类型。 加密过程可逆,加密后的数据可以通过密钥解密还原原始数据。 注:此段引用自《大数据时代下的隐私保护(三)》 更详细的介绍见: https://blog.csdn.net/scuLVLV/article/details/71191773 https://anquan.baidu.com/article/193 算法实现 由于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> FF1算法实现 // 映射字符表,规定了明文和密文的字符范围 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); FF3算法实现 // 映射字符表,规定了明文和密文的字符范围 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) 两种方式对比如下: 掩码:不可逆,长度保持,字符不保持 FPE : 可逆, 长度保持,字符保持