[{"data":1,"prerenderedAt":1082},["ShallowReactive",2],{"category-data-rsa":3},[4],{"id":5,"title":6,"body":7,"description":1067,"extension":1068,"meta":1069,"navigation":197,"ogImage":1071,"path":1078,"seo":1079,"stem":1080,"__hash__":1081},"content/blogs/19. ctf-crypto-rsa-deep-dive.md","RSA 深入实战：原理、小 n 分解与共模攻击",{"type":8,"value":9,"toc":1055},"minimark",[10,15,19,22,58,72,76,102,106,114,117,132,136,143,149,253,256,262,269,273,278,283,288,307,309,315,322,326,331,416,418,424,434,438,448,477,481,485,495,501,505,510,515,522,528,531,537,541,720,722,728,732,805,809,874,883,887,890,896,899,903,908,922,924,930,934,943,993,995,1001,1005,1040,1044,1051],[11,12,14],"h3",{"id":13},"一现实背景dh-与公钥密码学","一、现实背景：DH 与公钥密码学",[16,17,18],"p",{},"HTTPS（TLS）流程中：先用 DH 协商对称密钥，再用 RSA/ECDSA 证书认证身份。DH 解决\"公开信道建立共享密钥\"，RSA 解决\"身份认证与加密\"。",[16,20,21],{},"DH 最小实现（见密码学全景篇）：",[23,24,29],"pre",{"className":25,"code":26,"language":27,"meta":28,"style":28},"language-python shiki shiki-themes dracula","p, g = 0xffffffffffffffc5, 2\na, b = 1234567, 7654321\nA, B = pow(g, a, p), pow(g, b, p)\nassert pow(B, a, p) == pow(A, b, p)   # 双方共享密钥一致\n","python","",[30,31,32,40,46,52],"code",{"__ignoreMap":28},[33,34,37],"span",{"class":35,"line":36},"line",1,[33,38,39],{},"p, g = 0xffffffffffffffc5, 2\n",[33,41,43],{"class":35,"line":42},2,[33,44,45],{},"a, b = 1234567, 7654321\n",[33,47,49],{"class":35,"line":48},3,[33,50,51],{},"A, B = pow(g, a, p), pow(g, b, p)\n",[33,53,55],{"class":35,"line":54},4,[33,56,57],{},"assert pow(B, a, p) == pow(A, b, p)   # 双方共享密钥一致\n",[16,59,60,61,64,65,67,68,71],{},"RSA 的安全基础是：已知 ",[30,62,63],{},"n"," 求 ",[30,66,16],{},"、",[30,69,70],{},"q","（分解）在计算上不可行。CTF 题把参数做小或做错，让分解或绕过分解成为可能。",[11,73,75],{"id":74},"二环境准备","二、环境准备",[23,77,81],{"className":78,"code":79,"language":80,"meta":28,"style":28},"language-bash shiki shiki-themes dracula","pip3 install pycryptodome sympy gmpy2\n","bash",[30,82,83],{"__ignoreMap":28},[33,84,85,89,93,96,99],{"class":35,"line":36},[33,86,88],{"class":87},"sAOxA","pip3",[33,90,92],{"class":91},"s-mGx"," install",[33,94,95],{"class":91}," pycryptodome",[33,97,98],{"class":91}," sympy",[33,100,101],{"class":91}," gmpy2\n",[11,103,105],{"id":104},"三核心知识rsa-公式","三、核心知识：RSA 公式",[23,107,112],{"className":108,"code":110,"language":111,"meta":28},[109],"language-text","n = p × q\nφ(n) = (p-1)(q-1)\ne × d ≡ 1 (mod φ(n))        # d 是 e 的模逆元\n加密：c = m^e mod n\n解密：m = c^d mod n\n","text",[30,113,110],{"__ignoreMap":28},[16,115,116],{},"三个必须会用的 Python 运算：",[23,118,120],{"className":25,"code":119,"language":27,"meta":28,"style":28},"pow(3, 4, 7)        # 快速幂取模 = 4\npow(e, -1, phi)     # 求 e 在模 phi 下的逆元\n",[30,121,122,127],{"__ignoreMap":28},[33,123,124],{"class":35,"line":36},[33,125,126],{},"pow(3, 4, 7)        # 快速幂取模 = 4\n",[33,128,129],{"class":35,"line":42},[33,130,131],{},"pow(e, -1, phi)     # 求 e 在模 phi 下的逆元\n",[11,133,135],{"id":134},"四核心步骤-1手算验证","四、核心步骤 1：手算验证",[16,137,138,142],{},[139,140,141],"strong",{},"目的","：用最小参数亲手跑通 RSA 的生成与加解密，确认公式理解正确。",[16,144,145,148],{},[139,146,147],{},"思路","：先算 n 与 φ(n)，再求 d（e 的模逆元），最后验证 pow(c,d,n) 能还原 m。这四步是后面所有攻击的基础。",[23,150,152],{"className":25,"code":151,"language":27,"meta":28,"style":28},"p, q, e = 61, 53, 17\nn = p * q\n# n = 3233，公钥模数。\nphi = (p - 1) * (q - 1)\n# φ(n) = 60 × 52 = 3120，欧拉函数值。\nd = pow(e, -1, phi)\n# pow(e, -1, phi)：求 e 在模 phi 下的乘法逆元，即私钥 d = 2753。\n\nm = 65\nc = pow(m, e, n)\n# pow(m, e, n)：快速幂取模，即 m^e mod n，加密得 c = 2790。\nprint(\"n =\", n)\nprint(\"phi =\", phi)\nprint(\"d =\", d)\nprint(\"c =\", c)\nprint(\"解密 =\", pow(c, d, n))\n# pow(c, d, n)：用私钥解密，应还原 65，验证公式正确。\n",[30,153,154,159,164,169,174,180,186,192,199,205,211,217,223,229,235,241,247],{"__ignoreMap":28},[33,155,156],{"class":35,"line":36},[33,157,158],{},"p, q, e = 61, 53, 17\n",[33,160,161],{"class":35,"line":42},[33,162,163],{},"n = p * q\n",[33,165,166],{"class":35,"line":48},[33,167,168],{},"# n = 3233，公钥模数。\n",[33,170,171],{"class":35,"line":54},[33,172,173],{},"phi = (p - 1) * (q - 1)\n",[33,175,177],{"class":35,"line":176},5,[33,178,179],{},"# φ(n) = 60 × 52 = 3120，欧拉函数值。\n",[33,181,183],{"class":35,"line":182},6,[33,184,185],{},"d = pow(e, -1, phi)\n",[33,187,189],{"class":35,"line":188},7,[33,190,191],{},"# pow(e, -1, phi)：求 e 在模 phi 下的乘法逆元，即私钥 d = 2753。\n",[33,193,195],{"class":35,"line":194},8,[33,196,198],{"emptyLinePlaceholder":197},true,"\n",[33,200,202],{"class":35,"line":201},9,[33,203,204],{},"m = 65\n",[33,206,208],{"class":35,"line":207},10,[33,209,210],{},"c = pow(m, e, n)\n",[33,212,214],{"class":35,"line":213},11,[33,215,216],{},"# pow(m, e, n)：快速幂取模，即 m^e mod n，加密得 c = 2790。\n",[33,218,220],{"class":35,"line":219},12,[33,221,222],{},"print(\"n =\", n)\n",[33,224,226],{"class":35,"line":225},13,[33,227,228],{},"print(\"phi =\", phi)\n",[33,230,232],{"class":35,"line":231},14,[33,233,234],{},"print(\"d =\", d)\n",[33,236,238],{"class":35,"line":237},15,[33,239,240],{},"print(\"c =\", c)\n",[33,242,244],{"class":35,"line":243},16,[33,245,246],{},"print(\"解密 =\", pow(c, d, n))\n",[33,248,250],{"class":35,"line":249},17,[33,251,252],{},"# pow(c, d, n)：用私钥解密，应还原 65，验证公式正确。\n",[16,254,255],{},"实际输出：",[23,257,260],{"className":258,"code":259,"language":111,"meta":28},[109],"n = 3233\nphi = 3120\nd = 2753\nc = 2790\n解密 = 65\n",[30,261,259],{"__ignoreMap":28},[16,263,264,265,268],{},"攻击者只有 ",[30,266,267],{},"(n=3233, e=17, c=2790)","，没有 d。要解密，第一步就是分解 n。",[11,270,272],{"id":271},"五核心步骤-2小-n-分解","五、核心步骤 2：小 n 分解",[16,274,275,277],{},[139,276,141],{},"：拿到公钥后第一步永远是\"尝试分解 n\"——一旦分解成功，私钥直接可算。",[16,279,280,282],{},[139,281,147],{},"：n 小 → 本地工具直接分解；n 大 → 先查 FactorDB 是否有人分解过。分解出 p、q 后按公式算出 d 解密。",[284,285,287],"h4",{"id":286},"_51-用-sympy-分解","5.1 用 sympy 分解",[23,289,291],{"className":25,"code":290,"language":27,"meta":28,"style":28},"from sympy import factorint\n\nprint(factorint(3233))\n",[30,292,293,298,302],{"__ignoreMap":28},[33,294,295],{"class":35,"line":36},[33,296,297],{},"from sympy import factorint\n",[33,299,300],{"class":35,"line":42},[33,301,198],{"emptyLinePlaceholder":197},[33,303,304],{"class":35,"line":48},[33,305,306],{},"print(factorint(3233))\n",[16,308,255],{},[23,310,313],{"className":311,"code":312,"language":111,"meta":28},[109],"{53: 1, 61: 1}\n",[30,314,312],{"__ignoreMap":28},[16,316,317,318,321],{},"得到 ",[30,319,320],{},"p=53, q=61","。",[284,323,325],{"id":324},"_52-完整解密验证公式","5.2 完整解密（验证公式）",[16,327,328,330],{},[139,329,147],{},"：分解得到 p、q → 算 φ(n) → 算 d → pow(c,d,n) → long_to_bytes 转回文本。",[23,332,334],{"className":25,"code":333,"language":27,"meta":28,"style":28},"from Crypto.Util.number import long_to_bytes\n# long_to_bytes(x)：把大整数转成字节串（高位在前），用于查看解密出的文本。\n\nn = 3233\ne = 17\nc = 2790\np, q = 53, 61\n\nphi = (p - 1) * (q - 1)\nd = pow(e, -1, phi)\nm = pow(c, d, n)\n# 解密：m = c^d mod n。\n\nprint(\"m =\", m)\nprint(long_to_bytes(m))\n# 65 对应 ASCII 字符 'A'，说明这个最小例子只能承载一个字节的明文；\n# 真实题目的 n 足够大，能装下整个 flag，方法完全一样。\n",[30,335,336,341,346,350,355,360,365,370,374,378,382,387,392,396,401,406,411],{"__ignoreMap":28},[33,337,338],{"class":35,"line":36},[33,339,340],{},"from Crypto.Util.number import long_to_bytes\n",[33,342,343],{"class":35,"line":42},[33,344,345],{},"# long_to_bytes(x)：把大整数转成字节串（高位在前），用于查看解密出的文本。\n",[33,347,348],{"class":35,"line":48},[33,349,198],{"emptyLinePlaceholder":197},[33,351,352],{"class":35,"line":54},[33,353,354],{},"n = 3233\n",[33,356,357],{"class":35,"line":176},[33,358,359],{},"e = 17\n",[33,361,362],{"class":35,"line":182},[33,363,364],{},"c = 2790\n",[33,366,367],{"class":35,"line":188},[33,368,369],{},"p, q = 53, 61\n",[33,371,372],{"class":35,"line":194},[33,373,198],{"emptyLinePlaceholder":197},[33,375,376],{"class":35,"line":201},[33,377,173],{},[33,379,380],{"class":35,"line":207},[33,381,185],{},[33,383,384],{"class":35,"line":213},[33,385,386],{},"m = pow(c, d, n)\n",[33,388,389],{"class":35,"line":219},[33,390,391],{},"# 解密：m = c^d mod n。\n",[33,393,394],{"class":35,"line":225},[33,395,198],{"emptyLinePlaceholder":197},[33,397,398],{"class":35,"line":231},[33,399,400],{},"print(\"m =\", m)\n",[33,402,403],{"class":35,"line":237},[33,404,405],{},"print(long_to_bytes(m))\n",[33,407,408],{"class":35,"line":243},[33,409,410],{},"# 65 对应 ASCII 字符 'A'，说明这个最小例子只能承载一个字节的明文；\n",[33,412,413],{"class":35,"line":249},[33,414,415],{},"# 真实题目的 n 足够大，能装下整个 flag，方法完全一样。\n",[16,417,255],{},[23,419,422],{"className":420,"code":421,"language":111,"meta":28},[109],"m = 65\nb'A'\n",[30,423,421],{"__ignoreMap":28},[16,425,426,429,430,433],{},[30,427,428],{},"65"," 对应的 ASCII 字符是 ",[30,431,432],{},"A","。真实的明文是 flag 对应的长整数，但解密公式完全相同。",[284,435,437],{"id":436},"_53-用-factordb-查","5.3 用 FactorDB 查",[16,439,440,441,447],{},"如果 n 太大本地分解不动，去 ",[442,443,444],"a",{"href":444,"rel":445},"https://factordb.com",[446],"nofollow"," 粘贴 n 查询，或：",[23,449,451],{"className":25,"code":450,"language":27,"meta":28,"style":28},"from factordb.factordb import FactorDB\n\nf = FactorDB(n)\nf.connect()\np, q = f.get_factor_list()\n",[30,452,453,458,462,467,472],{"__ignoreMap":28},[33,454,455],{"class":35,"line":36},[33,456,457],{},"from factordb.factordb import FactorDB\n",[33,459,460],{"class":35,"line":42},[33,461,198],{"emptyLinePlaceholder":197},[33,463,464],{"class":35,"line":48},[33,465,466],{},"f = FactorDB(n)\n",[33,468,469],{"class":35,"line":54},[33,470,471],{},"f.connect()\n",[33,473,474],{"class":35,"line":176},[33,475,476],{},"p, q = f.get_factor_list()\n",[11,478,480],{"id":479},"六核心步骤-3共模攻击","六、核心步骤 3：共模攻击",[284,482,484],{"id":483},"_61-场景","6.1 场景",[16,486,487,488,490,491,494],{},"同一个 ",[30,489,63],{},"、两个互质的 ",[30,492,493],{},"e1, e2","、同一明文：",[23,496,499],{"className":497,"code":498,"language":111,"meta":28},[109],"c1 = m^e1 mod n\nc2 = m^e2 mod n\n",[30,500,498],{"__ignoreMap":28},[284,502,504],{"id":503},"_62-数学原理","6.2 数学原理",[16,506,507,509],{},[139,508,141],{},"：理解为什么\"两个密文能拼出明文\"。",[16,511,512,514],{},[139,513,147],{},"：扩展欧几里得求出 a、b 使 a×e1+b×e2=1；把两个密文分别取 a、b 次方再相乘，指数恰好合并成 1，明文就还原了。验证方式：恢复结果与原始 m 相等。",[16,516,517,518,521],{},"扩展欧几里得算法求出 ",[30,519,520],{},"a, b"," 使：",[23,523,526],{"className":524,"code":525,"language":111,"meta":28},[109],"a × e1 + b × e2 = 1\n",[30,527,525],{"__ignoreMap":28},[16,529,530],{},"则：",[23,532,535],{"className":533,"code":534,"language":111,"meta":28},[109],"c1^a × c2^b\n= m^(a×e1) × m^(b×e2)\n= m^(a×e1 + b×e2)\n= m^1 = m (mod n)\n",[30,536,534],{"__ignoreMap":28},[284,538,540],{"id":539},"_63-完整代码","6.3 完整代码",[23,542,544],{"className":25,"code":543,"language":27,"meta":28,"style":28},"def egcd(a, b):\n    # 扩展欧几里得算法：返回 (gcd, x, y)，满足 a*x + b*y = gcd(a,b)。\n    if b == 0:\n        return a, 1, 0\n    g, x, y = egcd(b, a % b)\n    return g, y, x - (a // b) * y\n\nn = 3233\ne1, e2 = 17, 19\nm = 65\nc1 = pow(m, e1, n)      # 2790：e1 加密结果\nc2 = pow(m, e2, n)      # 232：e2 加密结果\n\n_, a, b = egcd(e1, e2)\n# 忽略第一个返回值（gcd=1），取 a、b。\nprint(\"a =\", a, \"b =\", b, \"a*e1+b*e2 =\", a*e1 + b*e2)\n# 应输出 a=9, b=-8，验证 9×17 + (-8)×19 = 1。\n\n# 负指数要先取模逆元\nif a \u003C 0:\n    c1 = pow(pow(c1, -1, n), -a, n)\n    # pow(c1, -1, n)：c1 在模 n 下的逆元；再取 -a 次方（-a 为正）。\nelse:\n    c1 = pow(c1, a, n)\nif b \u003C 0:\n    c2 = pow(pow(c2, -1, n), -b, n)\nelse:\n    c2 = pow(c2, b, n)\n\nrecovered = (c1 * c2) % n\n# c1^a × c2^b = m^(a·e1 + b·e2) = m^1 = m (mod n)。\nprint(\"恢复 m =\", recovered)\n# 预期 65，与原始 m 相等，攻击成功。\n",[30,545,546,551,556,561,566,571,576,580,584,589,593,598,603,607,612,617,622,627,632,638,644,650,656,662,668,674,680,685,691,696,702,708,714],{"__ignoreMap":28},[33,547,548],{"class":35,"line":36},[33,549,550],{},"def egcd(a, b):\n",[33,552,553],{"class":35,"line":42},[33,554,555],{},"    # 扩展欧几里得算法：返回 (gcd, x, y)，满足 a*x + b*y = gcd(a,b)。\n",[33,557,558],{"class":35,"line":48},[33,559,560],{},"    if b == 0:\n",[33,562,563],{"class":35,"line":54},[33,564,565],{},"        return a, 1, 0\n",[33,567,568],{"class":35,"line":176},[33,569,570],{},"    g, x, y = egcd(b, a % b)\n",[33,572,573],{"class":35,"line":182},[33,574,575],{},"    return g, y, x - (a // b) * y\n",[33,577,578],{"class":35,"line":188},[33,579,198],{"emptyLinePlaceholder":197},[33,581,582],{"class":35,"line":194},[33,583,354],{},[33,585,586],{"class":35,"line":201},[33,587,588],{},"e1, e2 = 17, 19\n",[33,590,591],{"class":35,"line":207},[33,592,204],{},[33,594,595],{"class":35,"line":213},[33,596,597],{},"c1 = pow(m, e1, n)      # 2790：e1 加密结果\n",[33,599,600],{"class":35,"line":219},[33,601,602],{},"c2 = pow(m, e2, n)      # 232：e2 加密结果\n",[33,604,605],{"class":35,"line":225},[33,606,198],{"emptyLinePlaceholder":197},[33,608,609],{"class":35,"line":231},[33,610,611],{},"_, a, b = egcd(e1, e2)\n",[33,613,614],{"class":35,"line":237},[33,615,616],{},"# 忽略第一个返回值（gcd=1），取 a、b。\n",[33,618,619],{"class":35,"line":243},[33,620,621],{},"print(\"a =\", a, \"b =\", b, \"a*e1+b*e2 =\", a*e1 + b*e2)\n",[33,623,624],{"class":35,"line":249},[33,625,626],{},"# 应输出 a=9, b=-8，验证 9×17 + (-8)×19 = 1。\n",[33,628,630],{"class":35,"line":629},18,[33,631,198],{"emptyLinePlaceholder":197},[33,633,635],{"class":35,"line":634},19,[33,636,637],{},"# 负指数要先取模逆元\n",[33,639,641],{"class":35,"line":640},20,[33,642,643],{},"if a \u003C 0:\n",[33,645,647],{"class":35,"line":646},21,[33,648,649],{},"    c1 = pow(pow(c1, -1, n), -a, n)\n",[33,651,653],{"class":35,"line":652},22,[33,654,655],{},"    # pow(c1, -1, n)：c1 在模 n 下的逆元；再取 -a 次方（-a 为正）。\n",[33,657,659],{"class":35,"line":658},23,[33,660,661],{},"else:\n",[33,663,665],{"class":35,"line":664},24,[33,666,667],{},"    c1 = pow(c1, a, n)\n",[33,669,671],{"class":35,"line":670},25,[33,672,673],{},"if b \u003C 0:\n",[33,675,677],{"class":35,"line":676},26,[33,678,679],{},"    c2 = pow(pow(c2, -1, n), -b, n)\n",[33,681,683],{"class":35,"line":682},27,[33,684,661],{},[33,686,688],{"class":35,"line":687},28,[33,689,690],{},"    c2 = pow(c2, b, n)\n",[33,692,694],{"class":35,"line":693},29,[33,695,198],{"emptyLinePlaceholder":197},[33,697,699],{"class":35,"line":698},30,[33,700,701],{},"recovered = (c1 * c2) % n\n",[33,703,705],{"class":35,"line":704},31,[33,706,707],{},"# c1^a × c2^b = m^(a·e1 + b·e2) = m^1 = m (mod n)。\n",[33,709,711],{"class":35,"line":710},32,[33,712,713],{},"print(\"恢复 m =\", recovered)\n",[33,715,717],{"class":35,"line":716},33,[33,718,719],{},"# 预期 65，与原始 m 相等，攻击成功。\n",[16,721,255],{},[23,723,726],{"className":724,"code":725,"language":111,"meta":28},[109],"a = 9 b = -8 a*e1+b*e2 = 1\n恢复 m = 65\n",[30,727,725],{"__ignoreMap":28},[11,729,731],{"id":730},"七其他常见攻击速查","七、其他常见攻击速查",[733,734,735,748],"table",{},[736,737,738],"thead",{},[739,740,741,745],"tr",{},[742,743,744],"th",{},"场景",[742,746,747],{},"攻击",[749,750,751,770,778,786,794],"tbody",{},[739,752,753,763],{},[754,755,756,759,760],"td",{},[30,757,758],{},"e=3"," 且 ",[30,761,762],{},"m^e \u003C n",[754,764,765,766,769],{},"直接开立方根（",[30,767,768],{},"gmpy2.iroot(c, 3)","）",[739,771,772,775],{},[754,773,774],{},"同一明文发给 3 个不同 n",[754,776,777],{},"Håstad 广播攻击（中国剩余定理 + 开方）",[739,779,780,783],{},[754,781,782],{},"e 特别大（d 很小）",[754,784,785],{},"Wiener 攻击（连分数）",[739,787,788,791],{},[754,789,790],{},"p、q 很接近",[754,792,793],{},"Fermat 分解（平方差）",[739,795,796,799],{},[754,797,798],{},"泄露 dp",[754,800,801,802],{},"枚举 k，",[30,803,804],{},"p = (e*dp-1)//k + 1",[11,806,808],{"id":807},"八必学工具","八、必学工具",[733,810,811,824],{},[736,812,813],{},[739,814,815,818,821],{},[742,816,817],{},"工具",[742,819,820],{},"3 个核心功能",[742,822,823],{},"示例",[749,825,826,845,861],{},[739,827,828,831,842],{},[754,829,830],{},"pycryptodome",[754,832,833,67,836,67,839],{},[30,834,835],{},"long_to_bytes",[30,837,838],{},"inverse",[30,840,841],{},"pow(m,e,n)",[754,843,844],{},"见上文",[739,846,847,850,856],{},[754,848,849],{},"sympy",[754,851,852,855],{},[30,853,854],{},"factorint"," 分解",[754,857,858],{},[30,859,860],{},"factorint(3233)",[739,862,863,866,869],{},[754,864,865],{},"RsaCtfTool",[754,867,868],{},"自动尝试多种攻击、从公钥文件读取",[754,870,871],{},[30,872,873],{},"./RsaCtfTool.py -n N -e E --uncipher C --attack all",[16,875,876,877,882],{},"FactorDB（",[442,878,881],{"href":879,"rel":880},"https://factordb.com%EF%BC%89%E7%94%A8%E4%BA%8E%E6%9F%A5",[446],"https://factordb.com）用于查"," n 的已知分解。",[11,884,886],{"id":885},"九小-ctf-实战","九、小 CTF 实战",[16,888,889],{},"题目：",[23,891,894],{"className":892,"code":893,"language":111,"meta":28},[109],"n = 1000000016000000063\ne = 65537\nc = 856868007642616233\n",[30,895,893],{"__ignoreMap":28},[16,897,898],{},"说明：真实题目的 n 有数百位，这里为了能在本地秒级分解，使用 19 位 n；分解方法完全一致。",[284,900,902],{"id":901},"第一步分解","第一步：分解",[16,904,905,907],{},[139,906,147],{},"：n 只有 19 位，sympy 的 factorint 用试除/快速算法秒级分解；若 n 更大，改用 yafu 或查 FactorDB。",[23,909,911],{"className":25,"code":910,"language":27,"meta":28,"style":28},"from sympy import factorint\nprint(factorint(1000000016000000063))\n",[30,912,913,917],{"__ignoreMap":28},[33,914,915],{"class":35,"line":36},[33,916,297],{},[33,918,919],{"class":35,"line":42},[33,920,921],{},"print(factorint(1000000016000000063))\n",[16,923,255],{},[23,925,928],{"className":926,"code":927,"language":111,"meta":28},[109],"{1000000007: 1, 1000000009: 1}\n",[30,929,927],{"__ignoreMap":28},[284,931,933],{"id":932},"第二步解密","第二步：解密",[16,935,936,938,939,942],{},[139,937,147],{},"：与 5.2 完全相同的公式，只是参数换成实际值；输出 ",[30,940,941],{},"b'flag'"," 说明解密成功。",[23,944,946],{"className":25,"code":945,"language":27,"meta":28,"style":28},"from Crypto.Util.number import long_to_bytes\n\nn = 1000000016000000063\ne = 65537\nc = 856868007642616233\np, q = 1000000007, 1000000009\n\nphi = (p - 1) * (q - 1)\nd = pow(e, -1, phi)\nprint(long_to_bytes(pow(c, d, n)))\n",[30,947,948,952,956,961,966,971,976,980,984,988],{"__ignoreMap":28},[33,949,950],{"class":35,"line":36},[33,951,340],{},[33,953,954],{"class":35,"line":42},[33,955,198],{"emptyLinePlaceholder":197},[33,957,958],{"class":35,"line":48},[33,959,960],{},"n = 1000000016000000063\n",[33,962,963],{"class":35,"line":54},[33,964,965],{},"e = 65537\n",[33,967,968],{"class":35,"line":176},[33,969,970],{},"c = 856868007642616233\n",[33,972,973],{"class":35,"line":182},[33,974,975],{},"p, q = 1000000007, 1000000009\n",[33,977,978],{"class":35,"line":188},[33,979,198],{"emptyLinePlaceholder":197},[33,981,982],{"class":35,"line":194},[33,983,173],{},[33,985,986],{"class":35,"line":201},[33,987,185],{},[33,989,990],{"class":35,"line":207},[33,991,992],{},"print(long_to_bytes(pow(c, d, n)))\n",[16,994,255],{},[23,996,999],{"className":997,"code":998,"language":111,"meta":28},[109],"b'flag'\n",[30,1000,998],{"__ignoreMap":28},[284,1002,1004],{"id":1003},"第三步工具验证","第三步：工具验证",[23,1006,1008],{"className":78,"code":1007,"language":80,"meta":28,"style":28},"./RsaCtfTool.py -n 1000000016000000063 -e 65537 --uncipher 856868007642616233 --attack all\n",[30,1009,1010],{"__ignoreMap":28},[33,1011,1012,1015,1019,1022,1025,1028,1031,1034,1037],{"class":35,"line":36},[33,1013,1014],{"class":87},"./RsaCtfTool.py",[33,1016,1018],{"class":1017},"sIQBb"," -n",[33,1020,1021],{"class":1017}," 1000000016000000063",[33,1023,1024],{"class":1017}," -e",[33,1026,1027],{"class":1017}," 65537",[33,1029,1030],{"class":1017}," --uncipher",[33,1032,1033],{"class":1017}," 856868007642616233",[33,1035,1036],{"class":1017}," --attack",[33,1038,1039],{"class":91}," all\n",[11,1041,1043],{"id":1042},"十小结","十、小结",[16,1045,1046,1047,1050],{},"RSA 解题顺序：",[139,1048,1049],{},"先查 n 能否分解（FactorDB/sympy）→ 能分解就按公式解密 → 不能分解就检查共模、低指数、Wiener、Fermat 等结构性错误","。每个攻击对应一种\"实现错误\"，识别特征后套模板即可。",[1052,1053,1054],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sAOxA, html code.shiki .sAOxA{--shiki-default:#50FA7B}html pre.shiki code .s-mGx, html code.shiki .s-mGx{--shiki-default:#F1FA8C}html pre.shiki code .sIQBb, html code.shiki .sIQBb{--shiki-default:#BD93F9}",{"title":28,"searchDepth":42,"depth":42,"links":1056},[1057,1058,1059,1060,1061,1062,1063,1064,1065,1066],{"id":13,"depth":48,"text":14},{"id":74,"depth":48,"text":75},{"id":104,"depth":48,"text":105},{"id":134,"depth":48,"text":135},{"id":271,"depth":48,"text":272},{"id":479,"depth":48,"text":480},{"id":730,"depth":48,"text":731},{"id":807,"depth":48,"text":808},{"id":885,"depth":48,"text":886},{"id":1042,"depth":48,"text":1043},"RSA的DH 与公钥密码学背景、数论公式与小数字手算、小 n 分解解密、共模攻击的数学推导与代码。","md",{"date":1070,"image":1071,"alt":1072,"tags":1073,"published":197},"14th Aug 2026","/blogs-img/blog7.png","RSA 深入实战",[1074,1075,1076,1077],"ctf","crypto","rsa","example","/blogs/ctf-crypto-rsa-deep-dive",{"title":6,"description":1067},"blogs/19. ctf-crypto-rsa-deep-dive","cUGS-VePAPrg-FWNvg-OJ725RRZNhFybQstAdcvf9qo",1786796568787]