Python解密中如何还原pow(b, xyz, abc)中的b值?
这问题我之前帮朋友处理过类似的,本质是模幂的逆求解问题,咱们一步步拆解来解决:
核心问题拆解
首先得明确你手头的已知条件——既然是基于现有加密代码开发,你肯定能拿到这两个关键参数:
- 加密时的模数
abc(咱们后面统一叫m) - 每个数组元素对应的指数
xyz(后面叫e_i,如果所有加密用的是同一个指数,那就是e)
因为加密后的每个值都是c_i = pow(b, e_i, m),你的目标是从c_i、e_i、m反推b。这里的关键是:如果原始的b本身就在[0, m-1]范围内(加密场景里基本都是这么设计的,不然模运算就失去意义了),那还原出b mod m就是你要的精确值;如果b大于m,那除非有额外的范围约束(比如原始b是某个固定长度的整数),否则没法还原出绝对精确的b——毕竟模运算天生会丢失m倍数的信息。
分场景解决思路
场景1:所有加密用的是同一个指数e
这时候问题简化为求模m的e次根,步骤如下:
- 计算欧拉函数
φ(m):- 如果
m是质数,φ(m) = m-1 - 如果
m是合数,需要先对m做质因数分解,再用欧拉函数的乘积公式计算(比如m = p1^k1 * p2^k2...,则φ(m) = m * Π(1-1/pi))
- 如果
- 判断
e和φ(m)是否互质:- 如果互质,求
e在模φ(m)下的逆元d(可以用扩展欧几里得算法计算),然后b = pow(c, d, m),这就是唯一解 - 如果不互质,那会有多个可能的
b,这时候你需要结合其他加密值(如果有的话)或者业务逻辑来确定唯一解
- 如果互质,求
举个实际例子:
假设m=11(质数),e=3,φ(m)=10,gcd(3,10)=1,逆元d=7(因为3*7=21 ≡1 mod10)。如果加密值c=8(对应b=2,因为pow(2,3,11)=8),那解密时计算pow(8,7,11),结果就是2,完美还原。
场景2:数组元素对应不同的指数e_i
这种情况反而更容易锁定唯一解,因为你有多个联立的模幂等式:c1 = b^e1 mod mc2 = b^e2 mod m
...
你可以用以下方法:
- 先计算几个指数的最大公约数
g = gcd(e1, e2, ...) - 通过扩展欧几里得算法找到整数
k1, k2,...使得k1*e1 + k2*e2 + ... = g - 结合等式得到
b^g ≡ (c1^k1 * c2^k2 * ...) mod m - 接下来就转化为场景1的问题:求
b^g ≡ C mod m的根,其中C是上面计算出的结果 - 如果
g=1,那直接就能得到b ≡ C mod m,一步到位
另外,如果m是大质数或者难以分解的合数,也可以用Baby-step Giant-step算法来求解离散对数的逆问题(本质上就是已知c = b^e mod m求b),这个算法比暴力枚举高效得多。
关键注意事项
- 如果原始
b超出了[0, m-1],那你只能得到b mod m的值,除非你知道b的范围(比如是32位整数),可以通过b = k*m + b0(b0是还原出的模值)来枚举可能的k,验证是否符合加密逻辑 - 当
m是大合数时,质因数分解会比较耗时,这时候可以考虑用通用的模n次根算法,或者借助Python的sympy库(里面有现成的nthroot_mod函数)来简化计算
内容的提问来源于stack exchange,提问作者Mahi




