题目所给的文件内容为from Crypto.Util.number import * from secret import n,o,_,flag def any(m): return bytes_to_long(m)^o^pow(2,2**_,n) print(n,o,_,any(flag)) #(126176329335043454027341235009057683290541781096785538088437185779950106283534462102786883,22456023784134158064387550786352078427103553489348641216173010466267938277785173301732037264951635050700506776189809535326121257316490294752439819127486709456258090566784874248887194200916292508316349668172694553726134727726937633467532396106605496205841004277926961591604901357597262377953003319850049478502819166543968493292912201066602832545685929727421332846592671475883986049409546411338070434784675992855275254782158499562211464363321053581615280674425860714715529804670567409115827118589244016504450514019111124308126165185658681843519312254372108072512792854040590016772780908271525769845284796145687079308339,1138895128842708275167,22456023784134158064387550786352078427103553489348641216173010466267938277785173301732037264951635050700506776189809535326121257316490294752439819127486709456258090566784874248887194200916292508316349668172694553726134727726937633467532396106605496205841004277926961591604901357597262377953003319850049478502819166543968493292912201066602832545685929727421332846592671475883986049409546411338070434784675992855275254782158499562211464363321053581615280674425860714715529804670567409115827118589244016504450514019111124308126165145471041075065947806083270394708336810934202426175949363009508477208686445248781032485832)该代码中定义了一个any()加密函数函数输入一个m也就是明文。bytes_to_long()函数将m转换成长整数然后异或变量o和pow(2,2**_,n)很容易看出这个题目解密的核心是异或的自反性即A^B^BA所以直接利用公式M cipher^o^pow(2,2**_,n)所以给出如下代码from Crypto.Util.number import long_to_bytes n 126176329335043454027341235009057683290541781096785538088437185779950106283534462102786883 o 22456023784134158064387550786352078427103553489348641216173010466267938277785173301732037264951635050700506776189809535326121257316490294752439819127486709456258090566784874248887194200916292508316349668172694553726134727726937633467532396106605496205841004277926961591604901357597262377953003319850049478502819166543968493292912201066602832545685929727421332846592671475883986049409546411338070434784675992855275254782158499562211464363321053581615280674425860714715529804670567409115827118589244016504450514019111124308126165185658681843519312254372108072512792854040590016772780908271525769845284796145687079308339 _ 1138895128842708275167 cipher 22456023784134158064387550786352078427103553489348641216173010466267938277785173301732037264951635050700506776189809535326121257316490294752439819127486709456258090566784874248887194200916292508316349668172694553726134727726937633467532396106605496205841004277926961591604901357597262377953003319850049478502819166543968493292912201066602832545685929727421332846592671475883986049409546411338070434784675992855275254782158499562211464363321053581615280674425860714715529804670567409115827118589244016504450514019111124308126165145471041075065947806083270394708336810934202426175949363009508477208686445248781032485832 plain_int cipher ^ o ^ pow(2, 2**_, n) flag long_to_bytes(plain_int) print(flag.decode())但是很显然运行结果出现内存溢出的报错这是因为Python 的内置函数pow(a,b,c)中会优先计算指数的表达式也就是优先计算2**_在题目中这个数字数量级庞大造成了内存的溢出。但是pow(a,b,c)函数在每次计算的时候会不断的取模会将结果的大小限制在c以内。因此我们需要将2**_也交给pow函数去处理即写成嵌套形式pow(2, pow(2, _, n), n)。然后依然报错用几种不同的方式解码不直接用decodefrom Crypto.Util.number import long_to_bytes n 126176329335043454027341235009057683290541781096785538088437185779950106283534462102786883 o 22456023784134158064387550786352078427103553489348641216173010466267938277785173301732037264951635050700506776189809535326121257316490294752439819127486709456258090566784874248887194200916292508316349668172694553726134727726937633467532396106605496205841004277926961591604901357597262377953003319850049478502819166543968493292912201066602832545685929727421332846592671475883986049409546411338070434784675992855275254782158499562211464363321053581615280674425860714715529804670567409115827118589244016504450514019111124308126165185658681843519312254372108072512792854040590016772780908271525769845284796145687079308339 _ 1138895128842708275167 cipher 22456023784134158064387550786352078427103553489348641216173010466267938277785173301732037264951635050700506776189809535326121257316490294752439819127486709456258090566784874248887194200916292508316349668172694553726134727726937633467532396106605496205841004277926961591604901357597262377953003319850049478502819166543968493292912201066602832545685929727421332846592671475883986049409546411338070434784675992855275254782158499562211464363321053581615280674425860714715529804670567409115827118589244016504450514019111124308126165145471041075065947806083270394708336810934202426175949363009508477208686445248781032485832 mod_pow_result pow(2, pow(2, _, n), n) plain_int cipher ^ o ^ mod_pow_result flag_bytes long_to_bytes(plain_int) print(解密成功原始字节为:) print(flag_bytes) print(十六进制:, flag_bytes.hex()) # 尝试安全解码 try: print(UTF-8 解码:, flag_bytes.decode(utf-8)) except UnicodeDecodeError: print(UTF-8 解码失败尝试 GBK 或 Latin-1...) print(GBK 解码:, flag_bytes.decode(gbk, errorsreplace)) print(Latin-1 解码:, flag_bytes.decode(latin-1))运行出现乱码说明我们解密的逻辑与出题人的逻辑存在一些偏差。当计算pow(base,exp,n)的模运算的时候如果指数exp极大根据欧拉定理指数部分实际上是对ϕ(n) 欧拉函数取模而不是对 n 取模。这时需要因式分解n然后重新计算plain_int完整代码如下from Crypto.Util.number import long_to_bytes, inverse import sympy n 126176329335043454027341235009057683290541781096785538088437185779950106283534462102786883 o 22456023784134158064387550786352078427103553489348641216173010466267938277785173301732037264951635050700506776189809535326121257316490294752439819127486709456258090566784874248887194200916292508316349668172694553726134727726937633467532396106605496205841004277926961591604901357597262377953003319850049478502819166543968493292912201066602832545685929727421332846592671475883986049409546411338070434784675992855275254782158499562211464363321053581615280674425860714715529804670567409115827118589244016504450514019111124308126165185658681843519312254372108072512792854040590016772780908271525769845284796145687079308339 _ 1138895128842708275167 cipher 22456023784134158064387550786352078427103553489348641216173010466267938277785173301732037264951635050700506776189809535326121257316490294752439819127486709456258090566784874248887194200916292508316349668172694553726134727726937633467532396106605496205841004277926961591604901357597262377953003319850049478502819166543968493292912201066602832545685929727421332846592671475883986049409546411338070434784675992855275254782158499562211464363321053581615280674425860714715529804670567409115827118589244016504450514019111124308126165145471041075065947806083270394708336810934202426175949363009508477208686445248781032485832 # 1. 分解 n factors sympy.factorint(n) print(n 的因子:, factors) # 2. 计算 phi(n) # phi(n) n * ∏(1 - 1/p) for all prime factors p phi_n n for p in factors.keys(): phi_n phi_n * (p - 1) // p print(phi(n) , phi_n) # 3. 使用 phi(n) 重新计算模幂 # 加密时: pow(2, 2**_, n) 实际上等价于 pow(2, (2**_) % phi_n, n) mod_pow_result pow(2, pow(2, _, phi_n), n) # 4. 异或解密 plain_int cipher ^ o ^ mod_pow_result flag_bytes long_to_bytes(plain_int) print(flag 为:) print(flag_bytes)