如何实现整数的可逆加密解密,保证加密结果仍为整数
整数到整数可逆加解密实现方案
完全存在可落地的实现方式,核心是构造整数域上的可逆双射映射,全程不做Hex、Base64这类转字符串的编码操作,即可保证输入输出均为纯整数。
方案1:保留格式加密(FPE)
这是最适配你需求的标准化方案,设计目标就是让加密后的数据和原始数据格式、长度、取值范围完全一致:如果原始值是32位整数,输出就是32位整数;如果原始序列最大值为10000,输出就永远是0-9999之间的整数,不会出现字母、不会变长。
- 优先选用NIST标准化的FF1、FF3-1算法,不需要从零设计密码逻辑,只要将加密域配置为对应整数范围、基数设为10,就能直接得到纯整数密文。
- 你之前查到AES、Feistel输出字母数字混合串,本质是算法输出二进制结果后,额外做了Hex或Base64编码导致的,不是加密算法本身必须输出字符串。
方案2:整数版Feistel结构(轻量场景适用)
如果你的整数取值范围在2^32以内,不需要处理超大整数,可以直接实现全程整数运算的Feistel密码,不需要做字节流转换:
- 核心逻辑是将输入整数拆为左右两部分,多轮迭代中用轮函数对右半段做混淆,和左半段做运算后交换位置,最终拼接得到整数密文,逆向迭代即可解密。
- 以下是可直接运行的32位整数加解密示例:
MASK32 = 0xFFFFFFFF # 自行保管轮密钥,不要泄露 ROUND_KEYS = [0x12345678, 0x9abcdef0, 0x13579bdf, 0x2468ace0] def round_func(right: int, key: int) -> int: # 可替换为更复杂的整数混淆逻辑 return ((right * 1103515245 + 12345) & MASK32) ^ key def encrypt_int(plain: int) -> int: left = (plain >> 16) & 0xFFFF right = plain & 0xFFFF for key in ROUND_KEYS: left, right = right, (left ^ round_func(right, key)) & 0xFFFF return (left << 16) | right def decrypt_int(cipher: int) -> int: left = (cipher >> 16) & 0xFFFF right = cipher & 0xFFFF for key in reversed(ROUND_KEYS): right, left = left, (right ^ round_func(left, key)) & 0xFFFF return (left << 16) | right # 测试:加密原始值3 cipher = encrypt_int(3) # 输出为类似1598203907的纯整数 print(decrypt_int(cipher)) # 解密后输出3
- 如果你的整数取值范围不是2的整数次幂(比如最大值为10000),可以用循环重试的方式适配:如果加密结果超出取值范围,就将结果再次传入加密函数计算,直到结果落在合法区间即可,解密时执行相同逻辑,不会破坏可逆性。
方案3:基于模幂运算的RSA式置换(大整数场景适用)
如果需要处理的整数取值范围较大,可以直接用RSA算法的核心数学逻辑做整数加密,全程为整数运算:
- 选取两个大素数p、q,计算模数
n = p*q,欧拉函数值φ = (p-1)*(q-1),选取公钥e满足e与φ互质,计算私钥d满足e*d mod φ = 1。 - 加密逻辑:
密文 = 明文^e mod n - 解密逻辑:
明文 = 密文^d mod n - 注意模数n必须大于你所有可能用到的原始整数值,否则会出现解密失败的问题。
安全提示:生产环境高安全需求场景下,优先选择经过公开审计的标准FPE实现,不要自行设计密码核心逻辑;如果只是业务侧的轻量混淆需求,可使用自定义Feistel或模幂方案,密钥必须妥善存储,不能硬编码在前端可反编译的代码中。
内容的提问来源于stack exchange,提问作者Lordofdissapointment
相关产品推荐
相关产品推荐

