背包密码
例如,构造超递增序列
假设背包重量为70,我们发现
52<70,所以52在背包中,70-52=18
27>18,所以27不在背包中
13<18,所以13在背包中,18-13=5
6>5,所以6不在背包中
3<5,所以3在背包中,5-3=2
2=2,所以2在背包中,2-2=0.
DASCTF20247月-complex_enc
from Crypto.Util.number import *
import random
from secret import flag
def GET_KEY(n):
sum=2
key=[1]
for i in range(n):
r=random.randint(0,1)
x=sum+random.randint(0,n)*r
key.append(x)
sum+=x
return key
def enc(m,k):
cipher_list = []
for i in range(len(m)):
if m[i] == 1:
cipher_list.append(m[i] * k[i])
cipher = sum(cipher_list)
return cipher
m=bytes_to_long(flag)
m = [int(bit) for byte in flag for bit in format(byte, '08b')]
key=GET_KEY(len(m))
c=enc(m,key)
with open('output.txt', 'w') as f:
f.write(str(c))
f.write(str(key))
先用一个生成长度为n的密钥的函数,先随机取第一个元素放到key中,同时用sum记录密钥中元素之和,这里的r会随机取0、1,使后面每次生成的元素可能是前面所有数之和,也可能会多一点,将生成的所有元素作为密钥中的元素再将生成的密钥加到key中,并用sum记录所有密钥元素之和,如此循环往复,可以生成一段超递增序列作为密钥。
这段加密函数的两个参数,都为列表,且m为由0,1组成的列表,后面对明文进行了处理变成了这个形式,然后这里m只有0,1,就相当于求m和k两个向量的数量积,将m为1的项与k对应的项相乘在求和得到密文。
就是当W>an时,才有an。m[i]=1
EXP
from Crypto.Util.number import *
#对私钥重排
def relist(pub):
a = pub[:]
c = []
while a: # 当a不为空时
m = min(a)
c.append(m)
a.remove(m)
return c
#解密
def resolve(pub,a,w):
b=[]
for j in range(1,len(a)):
b.append(0) #用0填充方便后面替换
for i in range(1,len(a)):
an=a[len(a)-i-1]
id=pub.index(an)
if w<an:
None
else:
w=w-an
b[id:id+1]=[1] #将0替换成1
if w==0: #说明解密完成
return b
def decrypto(pub,w):
a=relist(pub)
m=resolve(pub,a,w)
return m
c=
key=
m=decrypto(key,c)
print(m)
ml=''
for i in range(len(m)):
ml+=str(m[i])
print(long_to_bytes(int(ml,2)))
BaseCTF-2024-week1-babypack
from Crypto.Util.number import *
import random
flag=b'BaseCTF{}'
m=bytes_to_long(flag)
bin_m=bin(m)[2:]
length=len(bin_m)
a=[1]
sum=1
for i in range(length-1):
temp=random.randint(2*sum+1,4*sum)
sum=sum+temp
a.append(temp)
a=a[::-1]
c=0
for i in range(length):
if bin_m[i]=='1':
c=c+a[i]
print("a=",a)
print("c=",c)
这里的a是一个超递增序列,每次我们比较一下c[i]和a[i],如果c>a,那么m[i]就等于1
EXP
from Crypto.Util.number import *
# a=
c=24886562958079299354043165561947473141759778607555940148388795515259155580420
0373536391905463203635903903983185413495772503475035384778216803353752385428842
7613513938991943920607437000388885418821419115067060003426834
bin_m=""
for i in a:
if c>=i:
bin_m+="1"
c=c-i
else:
bin_m+="0"
m=int(bin_m,2)
print(long_to_bytes(m))