RSA私钥存在5位未知字符时如何遍历合法私钥解密得到有意义明文
RSA私钥部分缺失的遍历解密方案
报错原因说明
你之前遍历报错的核心原因是大部分生成的候选值不满足RSA私钥的数学约束,且如果你调用的是标准加密库的私钥导入接口,这类接口要求输入完整的私钥结构(包含p、q、dp等衍生参数),仅传入d的数值会直接校验失败。
具体操作步骤
步骤1:统一转换参数为整数
首先把所有十六进制格式的参数转成十进制整数,方便后续运算:
e = int('1d35', 16) n = int('c4b361851de35f080d3ca7352cbf372d', 16) c = int('a02d51d0e87efe1defc19f3ee899c31d', 16) d_prefix = int('53a0a95b089cf23adb5cc73f07', 16) suffix_len = 5 suffix_max = 16 ** suffix_len
5位十六进制后缀总共有1048576种可能,遍历量级极低,普通设备即可快速跑完。
步骤2:直接调用模幂运算跳过私钥校验
不需要使用加密库的私钥导入接口,直接执行RSA解密的核心模幂运算,避免不必要的结构校验:
for suffix in range(suffix_max): d_candidate = d_prefix * suffix_max + suffix # 预校验:筛掉99%以上的错误候选 if pow(2, e * d_candidate, n) != 2: continue # 解密密文 m = pow(c, d_candidate, n) # 转大端字节串判断是否为可打印明文 m_bytes = m.to_bytes((m.bit_length() + 7) // 8, byteorder='big') try: # 可根据实际明文编码调整为gbk、ASCII等规则 plaintext = m_bytes.decode('utf-8') # 过滤不可见控制字符,仅保留可打印内容 if all(ord(c) >= 32 or ord(c) in (10, 13) for c in plaintext): print(f"找到合法明文:{plaintext}") print(f"对应私钥后缀:{hex(suffix)[2:].zfill(5)}") break except: continue
步骤3:验证结果
输出的可打印字符串即为目标明文,对应的5位十六进制后缀就是缺失的私钥部分。
内容的提问来源于stack exchange,提问作者mao
相关产品推荐
相关产品推荐

