4个版本
0.2.2 | 2023年12月8日 |
---|---|
0.2.1 | 2023年7月24日 |
0.2.0 | 2023年7月17日 |
0.1.0 | 2023年4月26日 |
在数据库实现中排名第74位
每月下载量2,728
用于cloudproof
255KB
2K SLoC
格式保留加密
此库提供了用于零信任环境的格式保留加密(FPE)技术。这些技术基于FPE-FF1,该技术已在NIST:800-38G中描述。
格式保留加密 (FPE)
FPE旨在在保留明文格式(字母表)的同时加密明文。FPE-FF1是一个标准化算法,使用对称加密,但它的速度和安全性不如AES或ChaCha等标准化的对称(或公钥)加密方法。它仅应在密文容器的格式受到限制的情况下使用(例如,无法更改的固定数据库模式)。
实现
FPE实现遵循NIST对FF1的规范(可在NIST SP 800-38G规范中找到)。
代码基于在GitHub上找到的cosmian_fpe
目录,该目录基于str4d/fpe
。根据这篇密码分析论文的建议,已将Feistel轮数增加到18。
实现还强制要求 radix^min_len > 1_000_000
。对于 Alphabet
和 Integer
FPE 功能,以下参数满足此要求
基数 | 示例字母表 | 最小文本长度 |
---|---|---|
2 | "01" | 20 |
10 | "01234567890" | 6 |
16 | "01234567890abcdef" | 5 |
使用FPE
Cosmian FPE 提出了 3 个结构
fpe::Alphabet
用于加密文本fpe::Integer
用于使用不同基数加密整数fpe::Float
用于加密浮点数
加密文本
fpe::Alphabet
结构提供使用 alphabet
加密明文的选项。属于字母表的明文字符会被加密,而其他字符在密文中保持其原始位置不变。
可以使用 Alphabet::instantiate()
方法实例化一个字母表
let hexadecimal_alphabet = Alphabet::instantiate("01234567890abcdef").unwrap();
有多个预定义的字母表可用
字母表::alpha()
字母表::alpha_lower()
字母表::alpha_upper()
字母表::numeric()
字母表::hexa_decimal()
字母表::alpha_numeric()
字母表::chinese()
字母表::latin1sup()
字母表::latin1sup_alphanum()
这些字母表可以使用 extend_with
方法轻松扩展
//0-9a-zA-Z
let mut alphabet = Alphabet::alphanumeric();
// add the space character
alphabet.extend_with(" ");
加密和解密字母数字文本
let key = [0_u8; 32];
let tweak = b"unique tweak";
let alphabet = Alphabet::alpha_numeric(); //0-9a-zA-Z
let ciphertext = alphabet.encrypt(&key, tweak, "alphanumeric").unwrap();
assert_eq!("jraqSuFWZmdH", ciphertext);
let plaintext = alphabet.decrypt(&key, tweak, &ciphertext).unwrap();
assert_eq!("alphanumeric", plaintext);
加密和解密信用卡号
let key = [0_u8; 32];
let tweak = b"unique tweak";
let alphabet = Alphabet::numeric(); //0-9
let ciphertext = alphabet
.encrypt(&key, tweak, "1234-1234-1234-1234")
.unwrap();
assert_eq!("1415-4650-5562-7272", ciphertext);
let plaintext = alphabet.decrypt(&key, tweak, &ciphertext).unwrap();
assert_eq!("1234-1234-1234-1234", plaintext);
注意:由于破折号字符不是字母表的一部分,它在加密和解密过程中被保留。
加密和解密带空格的中文文本
let key = [0_u8; 32];
let tweak = b"unique tweak";
let mut alphabet = Alphabet::chinese();
// add the space character to the alphabet
alphabet.extend_with(" ");
let ciphertext = alphabet.encrypt(&key, tweak, "天地玄黄 宇宙洪荒").unwrap();
assert_eq!("儖濣鈍媺惐墷礿截媃", ciphertext);
let plaintext = alphabet.decrypt(&key, tweak, &ciphertext).unwrap();
assert_eq!("天地玄黄 宇宙洪荒", plaintext);
注意:由于空格字符被添加到字母表中,它也被加密。
加密整数
fpe::Integer
结构提供加密介于 2(二进制)和 16(十六进制)之间的整数以及此基数的最大幂的能力。
要加密小于 u64::MAX 的十进制整数,请使用
let key = [0_u8; 32];
let tweak = b"unique tweak";
// decimal number with digits 0-9
let radix = 10_u32;
// the number of digits of the biggest number = radix^digits -1
// In this case 6 decimal digits -> 999_999
let digits = 6;
let itg = Integer::instantiate(radix, digits).unwrap();
let ciphertext = itg.encrypt(&key, tweak, 123_456_u64).unwrap();
assert_eq!(110_655_u64, ciphertext);
let plaintext = itg.decrypt(&key, tweak, ciphertext).unwrap();
assert_eq!(123_456_u64, plaintext);
还支持大无符号整数
let key = [0_u8; 32];
let tweak = b"unique tweak";
// decimal number with digits 0-9
let radix = 10_u32;
// the number of digits of the greatest number = radix^digits -1 = 10^20-1
let digits = 20;
// the value to encrypt: 10^17
let value = BigUint::from_str_radix("100000000000000000", radix).unwrap();
let itg = Integer::instantiate(radix, digits).unwrap();
let ciphertext = itg.encrypt_big(&key, tweak, &value).unwrap();
assert_eq!(
BigUint::from_str_radix("65348521845006160218", radix).unwrap(),
ciphertext
);
let plaintext = itg.decrypt_big(&key, tweak, &ciphertext).unwrap();
assert_eq!(
BigUint::from_str_radix("100000000000000000", radix).unwrap(),
plaintext
);
加密浮点数
fpe::Float
结构提供对加密类型为 f64
的浮点数的支持
let key = [0_u8; 32];
let tweak = b"unique tweak";
let flt = Float::instantiate().unwrap();
let ciphertext = flt.encrypt(&key, tweak, 123_456.789_f64).unwrap();
assert_eq!(1.170438892319619e91_f64, ciphertext);
let plaintext = flt.decrypt(&key, tweak, ciphertext).unwrap();
assert_eq!(123_456.789_f64, plaintext);
调整
Tweaks
是公共参数,应在可能的情况下随着每次加密实例的变化而变化。 Tweaks
在 NIST:800-38G: 附录 C 中描述。没有 tweak
的大小限制。
基准测试
运行快速入门
从当前目录(./crates/fpe)运行 cargo criterion
运行详细报告(Linux,MacOS)
-
安装 criterion 和 criterion-table
cargo install cargo-criterion cargo install criterion-table
-
从项目根目录运行
bash ./benches/benches.sh
-
基准测试随后在 ./benches/BENCHMARKS.md 中可用
依赖关系
~1.8–7.5MB
~61K SLoC