已知两质因数半数以上随机位的大整数分解
在解决RSA问题的过程中,我们往往会需要对一个大整数\(n\)进行质因数分解,在已知部分连续位的时候,我们经常会考虑使用Copper Smith方法来进行分解,但是若我们知道的是随机分散的位,Copper Smith方法将会失效,例如我们知道由两个质因数相乘得到的一个大整数\(n=pq\)如下:
104158954646372695568095796310479805403678314919693272509836778997179683485437763692891984254171869987446475357518587344178264028334102088429629785065036660148146855007349113784322098795994839040721664806905084554147298456659074384855277678993200563966327086005547016327991986225930798076081014377904788085807 |
又已知\(p\)的部分已知位(二进制表示,其中下划线为未知位,下同):
1010101111000___11000___11100___11010___0___0___0___100110000___0___0___0___11000___0___0___110110010___11001100100111010___100011000___0___0___0___11111000111111100___1101110010000___0___0___0___10110___0___0___0___0___0___1100101111000___0___1001111011110___0___10000___0___0___11010___1010101110110___0___0___0___0___10010___1011101011100___110111010___0___0___0___101010110___0___10000___1000101011000___0___0___0___101010000___11010___111010000___0___11110___0___10010___111010010___0___0___10100___0___0___ |
与\(q\)的部分已知位:
110111010___111011110___0___1000100110001110100111100___0___10110___11000___0___10110___11100___10000___0___0___11111100110010100___10000___11100___0___110010110___101110010___10010___11110___11110___0___1101111011000___101010110___10100___0___10100___1010101011010___0___0___100110110___0___10000___0___0___1000101110010___1111110010110___0___0___0___101110100___0___1100101111000___10100___0___0___0___0___0___0___10010___0___0___10100___10010___0___0___0___101011110___0___111110000___0___11110___0___10100___ |
显然,我们不能使用Copper Smith方法进行分解。
为应对这种情况,大佬y011d4在Github上发布了一个项目:y011d4/factor-from-random-known-bits,我们可以使用这个项目对上述的情况进行分解。
下载方法(推荐Linux):
首先确保系统中有Rust环境(因为这个项目主要是由Rust语言编写的)
- 使用
git clone https://github.com/y011d4/factor-from-random-known-bits.git
从Github上将该项目拉下来 cd factor-from-random-known-bits
进入项目文件夹后依次运行pip install -r requirements.txt
以及python setup.py install
在此之后就可以通过在Python中import factor
后使用这个方法进行分解了。
假若安装时报错,则有可能是系统中缺少
m4
这个宏处理器,可以通过sudo apt-get install m4
来安装这个宏处理器.
适用条件
- 已知\(p\)和\(q\)各50%以上的位
使用方法
这个库有两种使用方法:from_str
以及from_vector
from_str
以前面的数据为例,则可以通过如下代码对\(n\)进行分解:
import factor |
运行可以得到:
p = 8996460061304658501483536370547552107653796408964122401908135206811298639114618429412462572834106148254319079697639081615546751035691609086377055207530819 |
在这里,我们将未知的位置为下划线。
from_vector
以前面的数据为例,也可以通过如下代码对\(n\)进行分解:
import factor |
运行可以得到相同的结果。
在这种用法中,我们将未知的位设置为-1
注意:虽然适用条件中说已知\(p\)和\(q\)各50%以上的位就能使用,但是在某次测试中发现\(p\)与\(q\)均已知50.05%的位的时候其实是用不了的,这种时候就要通过爆破来知道尽可能多的位。
使用例:[BCACTF 5.0 Superstitious 2]
加密代码如下:
from Crypto.Util.number import * |
可以知道((1 << 1024) - 1)//3
如下:
101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101 |
所以我们可以知道\(p\)以及\(q\)约半数的位为0,以及最低位为1(因为\(p\),\(q\)必为奇数),所以我们将除了最低位的所有1都替换为下划线后通过Cyberchef统计之后可以看到:
有50.05%的位已知,显然可以利用本文说的方法来进行分解,但是实际操作发现只知道这么多位并不能直接分解\(p\)和\(q\),所以我们需要对\(p\)进行小范围爆破,所以我们可以通过如下脚本来进行求解:
from Crypto.Util.number import * |
在这里,我们通过爆破\(p\)的高16位中的8个未知位将\(p\)的已知位提升了8位,将补充的位全部置0再进行统计可以看到:
这时候\(p\)的已知部分变成了50.83%,应该可以进行有效分解了。运行脚本之后我们就可以得到flag:
bcactf{l4zy_cHall3nG3_WRITinG_f8b335319e464}