源码:
from Crypto.Util.number import getPrime,long_to_bytes,bytes_to_long
from Crypto.Cipher import AES
import hashlib
from random import randint
def gen512num():
order=[]
while len(order)!=512:
tmp=randint(1,512)
if tmp not in order:
order.append(tmp)
ps=[]
for i in range(512):
p=getPrime(512-order[i]+10)
pre=bin(p)[2:][0:(512-order[i])]+"1"
ps.append(int(pre+"0"*(512-len(pre)),2))
return ps
def run():
choose=getPrime(512)
ps=gen512num()
print ("gen over")
bchoose=bin(choose)[2:]
r=0
bchoose = "0"*(512-len(bchoose))+bchoose
for i in range(512):
if bchoose[i]=='1':
r=r^ps[i]
flag=open("flag","r").read()
key=long_to_bytes(int(hashlib.md5(long_to_bytes(choose)).hexdigest(),16))
aes_obj = AES.new(key, AES.MODE_ECB)
ef=aes_obj.encrypt(flag).encode("base64")
open("r", "w").write(str(r))
open("ef","w").write(ef)
gg=""
for p in ps:
gg+=str(p)+"\n"
open("ps","w").write(gg)
run()
这道题目的是求choose
r是根据choose的二进制位来选择异或ps,那么就可以找出异或了哪些ps来推断choose的状态
又因为ps从1-512位的都有,我们对r进行与加密相反的操作,倒着开始异或,一遇到r的最后一位是1的情况就根据ps的状态让choose在同位上为1,其他都为0
decrypt:
from Crypto.Util.number import getPrime,long_to_bytes,bytes_to_long
from Crypto.Cipher import AES
import hashlib
import base64
r=int(open('r').read())
ps=open('ps').read().split()
lp=[] #存储ps内每一个p去掉0之后的位数长度
for p in ps:
p=int(p)
while p%2==0:
p=p>>1
lp.append(len(bin(p)[2:]))
#print(lp)
m=['0']*512 #初始化choose
choose=''
for i in range(512):
if (r>>i)%2==1:
r^=int(ps[lp.index(512-i)])
m[lp.index(512-i)]='1' #根据ps的调用情况对choose赋值
for c in m:
choose+=c
ef=base64.b64decode(open('ef').read())
key=long_to_bytes(int(hashlib.md5(long_to_bytes(int(choose,2))).hexdigest(),16))
aes_obj = AES.new(key, AES.MODE_ECB)
m=aes_obj.decrypt(ef)
print(m)
这是个笨方法,网上找wp竟然有人用矩阵解,线代这种东西上学期学完之后就没再见过,学到了学到了
ps之间的异或可以看作模2下的加法
因此设ps为矩阵A,r为矩阵B,choose为矩阵C,则C*A=B,所以C=B*A^-1
ps=open(r'C:\Users\Lenovo\Desktop\attachment\sm\ps').read().split()
a=[]
for i in ps:
a.append(int(i))
A=[]
for i in a:
A.append([int(x) for x in bin(i)[2:].zfill(512)])
r=int(open(r'C:\Users\Lenovo\Desktop\attachment\sm\r').read())
B=[int(i) for i in bin(r)[2:].zfill(512)]
A=matrix(GF(2),A)
B=matrix(GF(2),B)
bchoose=B*A.inverse()
print(bchoose[0])#sagemath的格式无力吐槽
from Crypto.Util.number import *
from Crypto.Cipher import AES
import hashlib
import base64
bchoose=[1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1]
key=''
for i in bchoose:
key+=str(i)
key=int(key,2)
ef=base64.b64decode(open(r'C:\Users\Lenovo\Desktop\attachment\sm\ef').read())
key=long_to_bytes(int(hashlib.md5(long_to_bytes(key)).hexdigest(),16))
aes_obj = AES.new(key, AES.MODE_ECB)
ef=aes_obj.decrypt(ef)
print(ef)
太菜了太菜了,编程不行密码不行一道题做了一下午加一晚上