攻防世界题目练习——Crypto密码新手+引导模式(一)(持续更新)

密码学第2篇:
攻防世界题目练习——Crypto密码新手+引导模式(二)(持续更新)

1. base64

下载文件,打开是一个txt文件,解密工具base64解码,如图:
在这里插入图片描述

2. Caesar

打开文件看到字符如下:

oknqdbqmoq{kag_tmhq_xqmdzqp_omqemd_qzodkbfuaz}

联想到上一题拿到的flag的格式,可以看出是比较规律的一串字符。
上一题flag的格式为cyberpeace{xx_xx_xx_xx},因此猜测本题{}前面的内容为cyberpeace。
题目名字Caesar就是恺撒密码,也就是把每个字母移动相同的位数变成另一个字母,观察比较cyberpeace和oknqdbqmoq也看得出,字母相同的位置变化后的字母也相同,于是数一下移动的位数。

oknqdbqmoq
↓
cyberpeace
c->o后移12位
y->k后移12位
因此要解密就将密文每个字母向前移12位,可以参照前面cyberpeace对应的字母:
{kag_tmhq_xqmdzqp_omqemd_qzodkbfuaz}
kag->you
tmhq->have
xqmdzqp->learned
omqemd->caesar
qzodkbfuaz->encryption

得到flag:
cyberpeace{you_have_learned_caesar_encryption}

3. Morse

看到标题名字,大概是摩斯密码,打开文件内容如下:

11 111 010 000 0 1010 111 100 0 00 000 000 111 00 10 1 0 010 0 000 1 00 10 110

摩斯密码在线解密在线摩斯密码翻译器

解密结果:
MORSECODEISSOINTERESTING
转换为小写flag:
cyberpeace{morsecodeissointeresting}

4. Broadcast

题目提示说留下了明文。
解压下载的文件,打开task.py,直接看到flag:
在这里插入图片描述
不懂,这和密码有啥关系

5. hidden key

打开文件,代码如下:

from Crypto.Util.number import *
from secret import flag
import  random
import hashlib
import os

key=os.urandom(8)
#os.urandom(n)函数用来获取一个指定长度的bytes对象
#返回一个长为n个bytes的string
#本代码中返回一个8个字节的字符串

def rand(rng):
    return rng - random.randrange(rng)
#random.randrange([start,] stop [,step]),
#start -- 指定范围内的开始值,包含在范围内。如果 start 参数未传入参数,则采用默认值 0(零)。
#stop -- 指定范围内的结束值,不包含在范围内。
#step -- 指定递增基数。该参数是可选的,如果参数中没有传入宽度参数,则取默认值1
#也就是说,只有一个参数的话,就是stop值,本代码中就是在[0,rng)之间产生随机的整数值

m=[]
random.seed(int(hashlib.md5(key).hexdigest(), 16))
#设置随机种子后,是每次运行test.py文件的输出结果都一样,而不是每次调用随机函数生成的结果一样
#想要每次运行随机函数生成的结果都一样,可以在每个随机函数前都设置一模一样的随机种子

for i in range(len(flag)):
    rand(256)
    xor=flag[i]^rand(256)
    # 把flag的每一个字符和rand出来的值做异或
    m.append(xor)
print(m)
print(bytes_to_long(key)>>12)

# [140, 96, 112, 178, 38, 180, 158, 240, 179, 202, 251, 138, 188, 185, 23, 67, 163, 22, 150, 18, 143, 212, 93, 87, 209, 139, 92, 252, 55, 137, 6, 231, 105, 12, 65, 59, 223, 25, 179, 101, 19, 215]
# 2669175714787937

参考博客:
Python——os.urandom生成随机加密字符
Python random randrange()用法及代码示例
【python】random.seed()用法详解
Crypto中常用的数据类型互转方式

知道了输出结果,反过来尝试写解码的脚本:

# coding=gbk
# vscode里把编码改成了gbk,但是因为默认编码环境是utf-8,所以要在第一行加上coding=
from Crypto.Util.number import *
# from secret import flag
import random
import hashlib

key1 = 2669175714787937 << 12
# 由于低12位未知,所以需要低12位遍历每一个值循环爆破

m = [
    140, 96, 112, 178, 38, 180, 158, 240, 179, 202, 251, 138, 188, 185, 23, 67,
    163, 22, 150, 18, 143, 212, 93, 87, 209, 139, 92, 252, 55, 137, 6, 231,
    105, 12, 65, 59, 223, 25, 179, 101, 19, 215
]


def rand(rng):
    return rng - random.randrange(rng)


for k in range(1 << 12):
    key = long_to_bytes(key1 + k)
    random.seed(int(hashlib.md5(key).hexdigest(), 16))
    flag = []
    for i in range(len(m)):
        rand(256)
        xor = m[i] ^ rand(256)
        flag.append(xor)
    if all(ch < 256 for ch in flag):
        flag = bytes(flag)
        if (flag.startswith(b'flag')):
            print("key=", bytes_to_long(key))
            print(flag)

运行结果:
key= 10932943727771392887
b'flag{e319a58c-4dd6-4e6a-a3fb-f4b0d339faba}'

Non-UTF-8报错解决方法、append函数、bytes函数、bytes串参考博客如下:
Python出现报错:SyntaxError: Non-UTF-8 code starting with ‘\xa1‘ in file…
Python 列表 append()函数使用详解
python内置函数bytes()用法详解
Python bytes 字节串类型及用法

6. [简单] 初识RSA

题目:
p和q藏起来了,你能帮我找到它们吗

# coding=gbk
from Crypto.Util.number import bytes_to_long, inverse, getPrime
from flag import flag

m = bytes_to_long(flag)

p = getPrime(1024)
# getPrime先随机生成一个数字,然后判断是不是质数
q = getPrime(1024)
n = p * q
print(n)
e = 65537

c = pow(m, e, n)

pq = p * (q - 1)
qp = q * (p - 1)

print("c=", c)
print("n=", n)
print("pq=", pq)
print("qp=", qp)
'''
c= 8722269075970644434253339592758512788160408912707387632591552130175707843950684315083250494010055435391879036285103810263591951437829414438640307561645721347859659807138051841516634704123100270651976676182059252251162982609391666023674158274992400910869692389001622774140191223807887675081808561012755545464977015973615407965906513878979919700065923364884766974187303774330319143647840846354404070430118235352622445115153298578370521811697710289716188726587743282814946239856766713516166990341116198180068191759095913957606379780234116317390622824096667107736103270907349927467971817639795094030622157581511033950777
n= 10466186506773626671397261081802640650185744558208505628349249045496105597268556020207175016523119333667851114848452038431498926527983706092607207796937431312520131882751891731564121558651246025754915145600686076505962750195353958781726515647847167067621799990588328894365930423844435964506372428647802381074584935050067254029262890188260006596141011807724688556673520261743199388391094490191001701011230322653422314758778116196105077883955436582364267530633358016652912054880813710531145973799193443828969535902856467548523653920307742364119002349899553478815101092655897400295925170383678499125295006364960124859003
pq= 10466186506773626671397261081802640650185744558208505628349249045496105597268556020207175016523119333667851114848452038431498926527983706092607207796937431312520131882751891731564121558651246025754915145600686076505962750195353958781726515647847167067621799990588328894365930423844435964506372428647802381074488896197029704465200125337817646702009123916866455067019234171839614862660036737875747177391796376553159880972782837853473250804807544086701088829096838316550146794766718580877976153967582795248676367265069623900208276878140709691073369415161936376086988069213820933152601453587292943483693378833664901178324
qp= 10466186506773626671397261081802640650185744558208505628349249045496105597268556020207175016523119333667851114848452038431498926527983706092607207796937431312520131882751891731564121558651246025754915145600686076505962750195353958781726515647847167067621799990588328894365930423844435964506372428647802381074475956379708898904933143429835002718457573266164923043251954374464149976302585916538814746811455883837138715445492053610047383292461097590195481556557381952895539341802954749542143253491617052100969586396996063822508764438280468492894012685918249843558593322831683872737943676955669923498182824352081785243246
'''

都是很大的数,首先了解RSA算法:
RSA加密算法详细解说
RSA加密算法
RSA算法原理详解(简单易懂)
几个疑惑:
为什么要使e和d互为 m o d φ ( n ) mod\varphi (n) modφ(n)的逆?
首先有欧拉定理:如果两个正整数a和n互质,则n的欧拉函数φ(n)可以有等式成立:
a φ ( n ) m o d n = 1 a^{\varphi (n)}modn=1 aφ(n)modn=1
a φ ( n ) = k n + 1 a^{\varphi (n)}=kn+1 aφ(n)=kn+1,两边再同时乘以a,有 a φ ( n ) + 1 = a ( k n + 1 ) = k ′ n + a a^{\varphi (n)+1}=a(kn+1)=k'n+a aφ(n)+1=a(kn+1)=kn+a,也就是 a φ ( n ) + 1 m o d n = a a^{\varphi (n)+1}modn=a aφ(n)+1modn=a
在RSA算法中的应用便是: a e d m o d n = a a^{ed}modn=a aedmodn=a
拆成两个步骤来看,让a先乘e次方,再乘d次方,便是:
a e m o d n = m a^{e}modn=m aemodn=m
m d m o d n = a m^{d}modn=a mdmodn=a
故要使 e d = φ ( n ) + 1 ed=\varphi (n)+1 ed=φ(n)+1,也就是 e d m o d φ ( n ) = 1 edmod\varphi (n)=1 edmodφ(n)=1
(e,n)作为公钥,均为已知信息,想要知道私钥d就需要能求出 φ ( n ) \varphi (n) φ(n)
而RSA的安全性就在于大数n的不可分解性,一个很大的数n是很难在现有条件下分解成两个素数p、q的乘积的,因此想要破解出私钥d的值是很难的,也就很难被解密。

# coding=gbk
from Crypto.Util.number import bytes_to_long, long_to_bytes, inverse, getPrime

c = 8722269075970644434253339592758512788160408912707387632591552130175707843950684315083250494010055435391879036285103810263591951437829414438640307561645721347859659807138051841516634704123100270651976676182059252251162982609391666023674158274992400910869692389001622774140191223807887675081808561012755545464977015973615407965906513878979919700065923364884766974187303774330319143647840846354404070430118235352622445115153298578370521811697710289716188726587743282814946239856766713516166990341116198180068191759095913957606379780234116317390622824096667107736103270907349927467971817639795094030622157581511033950777
n = 10466186506773626671397261081802640650185744558208505628349249045496105597268556020207175016523119333667851114848452038431498926527983706092607207796937431312520131882751891731564121558651246025754915145600686076505962750195353958781726515647847167067621799990588328894365930423844435964506372428647802381074584935050067254029262890188260006596141011807724688556673520261743199388391094490191001701011230322653422314758778116196105077883955436582364267530633358016652912054880813710531145973799193443828969535902856467548523653920307742364119002349899553478815101092655897400295925170383678499125295006364960124859003
pq = 10466186506773626671397261081802640650185744558208505628349249045496105597268556020207175016523119333667851114848452038431498926527983706092607207796937431312520131882751891731564121558651246025754915145600686076505962750195353958781726515647847167067621799990588328894365930423844435964506372428647802381074488896197029704465200125337817646702009123916866455067019234171839614862660036737875747177391796376553159880972782837853473250804807544086701088829096838316550146794766718580877976153967582795248676367265069623900208276878140709691073369415161936376086988069213820933152601453587292943483693378833664901178324
qp = 10466186506773626671397261081802640650185744558208505628349249045496105597268556020207175016523119333667851114848452038431498926527983706092607207796937431312520131882751891731564121558651246025754915145600686076505962750195353958781726515647847167067621799990588328894365930423844435964506372428647802381074475956379708898904933143429835002718457573266164923043251954374464149976302585916538814746811455883837138715445492053610047383292461097590195481556557381952895539341802954749542143253491617052100969586396996063822508764438280468492894012685918249843558593322831683872737943676955669923498182824352081785243246

p = n - pq
q = n - qp

phi = (p - 1) * (q - 1)

e = 65537
d=inverse(e,phi)
# 看了WriteUp才知道原来有专门的求逆的函数,我还瞎折腾这么久T_T
m=pow(c,d,n)
flag=long_to_bytes(m)
print(flag)
#输出结果:
#b'flag{719014b3-c4e1-4f81-a7be-b4f0d65c9e10}'

# 下面是自己写求逆元的函数,但是对于大数不适用,a/b会报错。
'''
# 求d
# a*x+b*y=1,a为S,b为e,所求的逆元为y,
def ext_gcd(a, b):
    # return x,y,gcd(a,b)
    if b == 0:
        return 1,0
    else:
        x,y=ext_gcd(b,a%b)
        q=a/b
        x,y=y,(x-q*y)
        return x,y

x,d=ext_gcd(S,e)

m=pow(c,d,n)

flag=bytes_to_long(m)

print(flag)
'''

7. 简单的LFSR

学习博客:
线性反馈移位寄存器(Linear Feedback Shift Register, LFSR)
题目:
这是一个生成随机数的算法

from secret import secret
for b in secret: assert(b == '0' or b == '1')
assert(len(secret) == 128)
# a 01 string with length 128
# your flag is flag{md5(secret).hexdigest()}

def string2bits(s):
    return [int(b) for b in s]

def lfsr(state, mask):
    assert(len(state) == 128)
    assert(len(mask)  == 128)

    output = 0
    for i in range(128):
        output = output + (state[i] * mask[i])

    return output

if __name__ == '__main__':
    initState = [0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0]
    mask = string2bits(secret)
#将secret内容转成整型
    for i in range(256):
        state = initState[i:]
        #每次从i开始取后面的所有值
        output = lfsr(state, mask)
        #从initState[i]开始到initState[i+127]每一个和mask[0]到mask[127]相乘的积之和
        initState += [output]
        #并且将这个和追加到initState后面

    outputState = initState[128:]
    #输出的是每一轮添加到initState末尾的乘积之和
    print('outputState =', outputState)
    #
    # outputState = [31, 66, 128, 222, 385, 664, 1143, 2000, 3458, 6003, 10379, 17942, 31047, 53687, 92924, 160797, 278304, 481638, 833479, 1442422, 2496163, 4319845, 7475835, 12937561, 22389578, 38746915, 67054735, 116043520, 200822710, 347539886, 601445745, 1040850538, 1801275628, 3117252874, 5394657302, 9335889442, 16156509611, 27960142496, 48387281659, 83738092531, 144915522009, 250787996657, 434008851435, 751087316130, 1299817167363, 2249438425629, 3892834588915, 6736864173067, 11658686709797, 20176297502410, 34916709837729, 60426182042628, 104572380769600, 180970937597032, 313184800936842, 541991553121913, 937960088661442, 1623215570164618, 2809105439634215, 4861383488449105, 8413016146818879, 14559402864389777, 25196220721365800, 43604091771673155, 75460397027739861, 130590302153314191, 225997048627046433, 391106116962451401, 676840674047358730, 1171327366605398299, 2027076463289970382, 3508019282374090135, 6070910253447116278, 10506199749411485204, 18181825882182859769, 31465115864423937634, 54452920337985370536, 94235169707018163674, 163081560265112209496, 282225790871820528073, 488414489680745790033, 845240659945376349091, 1462757121910708796880, 2531419155626961478438, 4380824981460105751921, 7581370898424646092677, 13120173698498971899800, 22705518590912550882405, 39293730885686099313323, 68000969928723717268434, 117681162033195064953557, 203656740661184789826464, 352444412513853856490154, 609933476834387348179796, 1055539066458205919344242, 1826695472762162772755920, 3161243819621244340994611, 5470787351316040252901913, 9467638673598260118507327, 16384512191330329194463349, 28354719587732695891973236, 49070128760035595469947547, 84919814815174884654495265, 146960587438213290271803310, 254327147405947343219170013, 440133637427387650641676733, 761686751771954639615932308, 1318160346062225166536927204, 2281182774793880566386854202, 3947770745464875128215489476, 6831935621711193478803584270, 11823215517979626989252654459, 20461027873324936552011726278, 35409458704049766870463574070, 61278923692217093991616774374, 106048118957748860598268928024, 183524821535095103500935105397, 317604503036094959823791626415, 549640204006492782256703506357, 951196695803666227643791343005, 1646122586216645151673646795131, 2848747878127492747395146497119, 4929987925010971381846789176787, 8531741656523753626888968333475, 14764866932914585711739993009471, 25551792860485990447357753377411, 44219438031623458174827090101591, 76525303351860239321171606062486, 132433208420836012247860425341878, 229186346534231007543300455047052, 396625454174562824696341867974807, 686392332170111774628387415187708, 1187857281228776953526538661167132, 2055682813511567389589959681437591, 3557524878237416677051445431119245, 6156583679200434562674367324375645, 10654464521349051207718915685250792, 18438410026033851006551039004948926, 31909155416202798852780253976608864, 55221366589513932226781115179478434, 95565027912492621164419094117570641, 165382987128929746587819720020389833, 286208595645816231325692474821432127, 495307054513959920117280296979778603, 857168799202977606481906830566592959, 1483399728776458203402121501599814357, 2567142851419860475561591348189292465, 4442647717774532025797522076302827645, 7688360128977964468508623330874749520, 13305327189541069887965447505836108943, 23025941637865784521234444191415083701, 39848248807227476288131461546822173104, 68960607908058729168472941626927516912, 119341892941264496254850267375680858596, 206530769418287872448439164819365157712, 357418151038572249261836365381689027787, 618540932431735991718001801386896334770, 1070434962471260463170389697079661487176, 1852474022011964581139009223827365513544, 3205855677870125101423860144920010424249, 5547991769498476629256700835469967207037, 9601247144996961660705018593534913225922, 16615732425220501988109900409620796156745, 28754864847988594478375696246052761203187, 49762612400465240380187427652132912229336, 86118213596547492163397334421181607606370, 149034513167786192667574788821667110253623, 257916243121530494722068502259305736264048, 446344856986474817826595353109273441918350, 772435768089263602359077702861161388353409, 1336762385595787378549468975393213339116484, 2313375104267880490155624917599100889633507, 4003482167596451918353914186255524345816532, 6928348730257112541629154203810355027525535, 11990066177033590775605142065871666200189459, 20749776393589512464840020374644649655647874, 35909161302935015278730531942138798319507636, 62143699335409560081369603141161471393159562, 107544682943462043814216772302622710407400704, 186114746194704481727730115452186541297539854, 322086576510057527551600558671512063007190557, 557396793585831655018738502556644467159583633, 964620099559052960425720416252526682882655111, 1669352868873354804885622348664567494237803783, 2888949755545809136243688064556192446919868175, 4999560515746991945989073252770067125902428535, 8652142635098861248148452777057412533362877977, 14973230535426489152060521332311783517581989420, 25912382876992006096351135796067625851883928825, 44843468133024591960270046213401958144446811548, 77605237763877474989955856305494246316739147127, 134302122006319171731632762048131880552676359659, 232420652202367984596938247872208285088912788686, 402222680946414142984184322215356821073359953948, 696078784456971603910909918744734815016448573082, 1204620468022900362280402553035290601874308600586, 2084692860035604927076197374205039877760447754956, 3607729103106034863624554004184342562208475089341, 6243466138784576918107250594832177417637788944304, 10804821623826866941723224844111388709787418308073, 18698615116609470739339911758664365362637188157227, 32359461308280335893458609544003265039362932173740, 56000657248244594858300036379967633467510318826268, 96913653239119041752111865895809664169241405330164, 167716892009274048794745102986623447430717183044189, 290247606246426020117292750048691625438809474898504, 502296888062545512718475829352732508523042936581530, 869265269816240261877029457458234318249621243667628, 1504333646627354107869007496936781479204707239575364, 2603370684363759081777877568090078592049534352669947, 4505342904082185194291963661562434728467247085801567, 7796859204598587173314308958000104480418858953375158, 13493093589225451977147040588861591346827624626553088, 23350886533928418622148518003626067086836308029229306, 40410592153292809121198774051487713973447271440824879, 69933788415571610361075397290260005189363125951186151, 121026060286409890014591649872661507384922097295622585, 209445356819655999941471437498154462693217873859873519, 362462079567824464738504374835340908769751488853277318, 627269857492024846036766185061792395514128412691597750, 1085541071185182881358902065797900004206275433304525877, 1878616361292087979017649753948129817575491489985996469, 3251097104102362704835900720328806405351210311448488910, 5626285705844227224482132571164442587287950705132698177, 9736741115435595736854097976874400909429981720207988487, 16850215667245180941552990697851306753178430167486844006, 29160657006948951882262364132481449161390275730087294685, 50464868454466647556267645846637274956572498586114427735, 87333524327649631040132103644841977096784627243509857937, 151137706390139040826448707126591974417399010694640174718, 261555988593488478677610370284679511774525269175612894617, 452643730033345117036459086235348615186246366652477694168, 783336475835524143955537154153262203019092265959952337070, 1355626939379487620769121922144227585175531097052439217983, 2346021735820790423533561047507688175516954900918138334291, 4059979796110323903393797058491537625611005518946149411026, 7026122432346967683382009847205881024752630926437218981740, 12159271452933065576710291263470354882115951853620136774055, 21042599768180623908382939506716338579508214228553692875423, 36415915765826987773364669427220163018133640081486671468436, 63020678797925209300085103082659626905494796721119527734083, 109062366622625198169859916735972641477602693706580750774247, 188741220186912829686057249397861922209555075583934877024777, 326631901551406455092777938653826814900794821912935940782874, 565262845103114204256414747869081614169923740442179762058936, 978232936025018959853100287323851115023773163216042197843195, 1692910980111501346802672231436092377546116455476214539222026, 2929718966760270262844895994547637314231078419236801672684198, 5070114923366815738216357619638190602226980891746062079428250, 8774242726964718704518978915749604855301897112378619823447909, 15184534590503864395968205111669668293209355696392197598100449, 26278061583779512058870924747917968681797893736357134971437061, 45476304623307832769415233578427592641287934525440233150419102, 78700412341998941621862709864667467345902574612843786168968091, 136197409928206718914848388530217366761295027423898231594892758, 235700600786468895717413188934153824796333855958950958366797470]
    #

代码的计算方式已经写在注释里了,对于mask的每一个值,应该有如下计算式:
i n i t S t a t e [ 0 ] ∗ m a s k [ 0 ] + i n i t S t a t e [ 1 ] ∗ m a s k [ 1 ] + . . . + i n i t S t a t e [ 127 ] ∗ m a s k [ 127 ] = i n i t S t a t e [ 128 ] = o u t p u t S t a t e [ 0 ] initState[0]*mask[0]+initState[1]*mask[1]+...+initState[127]*mask[127]=initState[128]=outputState[0] initState[0]mask[0]+initState[1]mask[1]+...+initState[127]mask[127]=initState[128]=outputState[0]
i n i t S t a t e [ 1 ] ∗ m a s k [ 0 ] + i n i t S t a t e [ 2 ] ∗ m a s k [ 1 ] + . . . + i n i t S t a t e [ 128 ] ∗ m a s k [ 127 ] = i n i t S t a t e [ 129 ] = o u t p u t S t a t e [ 1 ] initState[1]*mask[0]+initState[2]*mask[1]+...+initState[128]*mask[127]=initState[129]=outputState[1] initState[1]mask[0]+initState[2]mask[1]+...+initState[128]mask[127]=initState[129]=outputState[1]

. . . ... ...
i n i t S t a t e [ 127 ] ∗ m a s k [ 0 ] + i n i t S t a t e [ 128 ] ∗ m a s k [ 1 ] + . . . + i n i t S t a t e [ 254 ] ∗ m a s k [ 127 ] = i n i t S t a t e [ 255 ] = o u t p u t S t a t e [ 127 ] initState[127]*mask[0]+initState[128]*mask[1]+...+initState[254]*mask[127]=initState[255]=outputState[127] initState[127]mask[0]+initState[128]mask[1]+...+initState[254]mask[127]=initState[255]=outputState[127]

由于前面128项式子中,mask的系数initState[0-127]有很多0,因此无法根据前128个式子计算出mask的值,需要从outputState[0]开始列方程组。

o u t p u t S t a t e [ 0 ] ∗ m a s k [ 0 ] + o u t p u t S t a t e [ 1 ] ∗ m a s k [ 1 ] + . . . + o u t p u t S t a t e [ 127 ] ∗ m a s k [ 127 ] = o u t p u t S t a t e [ 128 ] outputState[0]*mask[0]+outputState[1]*mask[1]+...+outputState[127]*mask[127]=outputState[128] outputState[0]mask[0]+outputState[1]mask[1]+...+outputState[127]mask[127]=outputState[128]
o u t p u t S t a t e [ 1 ] ∗ m a s k [ 0 ] + o u t p u t S t a t e [ 2 ] ∗ m a s k [ 1 ] + . . . + o u t p u t S t a t e [ 128 ] ∗ m a s k [ 127 ] = o u t p u t S t a t e [ 129 ] outputState[1]*mask[0]+outputState[2]*mask[1]+...+outputState[128]*mask[127]=outputState[129] outputState[1]mask[0]+outputState[2]mask[1]+...+outputState[128]mask[127]=outputState[129]
. . . ... ...
o u t p u t S t a t e [ 127 ] ∗ m a s k [ 0 ] + o u t p u t S t a t e [ 128 ] ∗ m a s k [ 1 ] + . . . + o u t p u t S t a t e [ 254 ] ∗ m a s k [ 127 ] = o u t p u t S t a t e [ 255 ] outputState[127]*mask[0]+outputState[128]*mask[1]+...+outputState[254]*mask[127]=outputState[255] outputState[127]mask[0]+outputState[128]mask[1]+...+outputState[254]mask[127]=outputState[255]

参考博客
crypto-简单的LFSR(xctf)

根据该博客的脚本,知道了有求解线性方程组的函数库,又去搜了一下:
python求解各种复杂的线性/非线性方程组
numpy应用之求解方程(线性方程组、超定方程组)
接下来尝试用python写求解的脚本:

import numpy as np
from numpy.linalg import lstsq # 解超定方程
from numpy.linalg import solve # 解线性方程

outputState = []#就上面outputState那一串,太长了这里不再重复

a=[]#系数
b=[]#等号后的常数

for i in range(128):
    a += [outputState[i:i + 128]]
    b += [outputState[i + 128]]

A = np.array(a, dtype=np.float64)
B = np.array(b, dtype=np.float64)
x = solve(A, B)
print(x)

安装numpy库:
NumPy 安装 | 菜鸟教程
对象和浮点类型报错解决:在后面增加类型参数dtype
python之numpy的基本使用
Numpy库使用入门(一)ndarray对象的基本操作
但是!!
用这个脚本只能求出来浮点数的解,把dtype改成int64会报错说数字太大,没有办法求出只有0或1的整数解。
实在不知道咋弄,只能还是参考别人的用sagemath了,网上没搜到怎么在python里调用sagemath库,心累
可以用在线网站:
Use SageMath Online

#sage
outputState = []#就上面outputState那一串,太长了这里不再重复
for i in range(128):
    a += outputState[i:i+128]
    b += [outputState[i+128]]

A = matrix(ZZ, 128, 128, a) 
B = matrix(ZZ, 128, 1, b) 
x =A.solve_right(B)
#print(x)#输出结果为全0或1组成的
#直接输出x的结果,会有回车的每个数单独一行的竖着排列的结果:
#[1]
#[1]
#...
#[0]这种
#因此后面把结果转成字符串时需要全部把'\n','[',']'用空的字符''替换掉
secret=x.str().replace('\n','').replace('[','').replace(']','')

matrix函数参数的使用参考博客:
R 矩阵 | 菜鸟教程
SageMath矩阵操作及解线性方程组

下面的是直接用python输出的结果,线上sagemath调用不了hashlib库。

import hashlib
#直接让secret='110...011'这一串字符时,md5会报错:
#TypeError: Strings must be encoded before hashing
#所以需要在前面加上b,采用字节输入,这是哈希函数可接受的
secret = b'11001010011010011011000010110011101110111001101101100100110100101110100000101001000010011001011101000100101011001110100001010011'
flag = hashlib.md5(secret).hexdigest()
print('flag{'+flag+'}')
#输出结果:
#flag{48eea154e05fefe7a657680a080ada3b}

参考博客:
Python 中 MD5 哈希函数的实现

8. baigeiRSA

题目代码如下:

import libnum
from Crypto.Util import number
from secret import flag

size = 128
e = 65537
p = number.getPrime(size)
q = number.getPrime(size)
n = p*q

m = libnum.s2n(flag)
c = pow(m, e, n)

print('n = %d' % n)
print('c = %d' % c)

output:

n = 88503001447845031603457048661635807319447136634748350130947825183012205093541
c = 40876621398366534035989065383910105526025410999058860023908252093679681817257

根据代码可知,flag被libnum.s2n(s)函数转换成了整型数字作为明文m,因此我们要计算私钥d解密,p、q未知,需要对n进行素数分解,不想下载工具,直接找线上网站。
参考博客:
libnum库的安装与使用
libnum库简单使用(进制字符串转换)
【转载】yafu的安装及使用(线下工具与线上网站)
线上网站:
http://www.factordb.com/index.php
http://www.atool.org/quality_factor.php
分解n得到p、q,然后进行解密:

# coding=gbk
import libnum
from Crypto.Util import number
from Crypto.Util.number import inverse

e = 65537
n = 88503001447845031603457048661635807319447136634748350130947825183012205093541
c = 40876621398366534035989065383910105526025410999058860023908252093679681817257

# 分解n得到n的两个因数:
p = 274539690398523616505159415195049044439
q = 322368694010594584041053487661458382819
phi = (p - 1) * (q - 1)

# 求e的逆
d = inverse(e, phi)
m = pow(c, d, n)
flag = libnum.n2s(m)
print(flag)

#输出结果:
#b'HSCTF{@Zh3n_Ba1_G3i!@}'

9. Railfence

题目:

ccehgyaefnpeoobe{lcirg}epriec_ora_g

看到题目字母猜测是分组栅栏密码,但是分几组试了一下感觉不太对,遂上网搜答案
Crypto入门 (七) Railfence (栏栅密码,正常型和W型)
参考博客如上,我就懒得写题解了,W型以前也没见过,长见识了
网站解密:

在这里插入图片描述

10. 幂数加密

题目文本内容如下:

8842101220480224404014224202480122

题目名字是幂数加密
了解幂数加密:
二进制幂数加密法
但是本题目出现了数字8,明显不可能是2^8,因此并不符合幂数加密条件。
参考博客:
Crypto入门 (六)幂数加密(云影密码)
认识到了有一种云影密码,以0为分割,运用1248可以表示出0-9的任何数字,也可以表示出1-26的数字。
因此:

88421 0122 048 02244 04 0142242 0248 0122
23    5    12  12    4  15      14   5
W     E    L   L     D  O       N    E
WELLDONE

11. 不仅仅是Morse

格式为cyberpeace{小写的你解出的答案}
题目内容为s1的内容,脚本如下:

s1='--/.-/-.--/..--.-/-..././..--.-/..../.-/...-/./..--.-/.-/-./---/-/...././.-./..--.-/-.././-.-./---/-.././..../..../..../..../.-/.-/.-/.-/.-/-.../.-/.-/-.../-.../-.../.-/.-/-.../-.../.-/.-/.-/.-/.-/.-/.-/.-/-.../.-/.-/-.../.-/-.../.-/.-/.-/.-/.-/.-/.-/-.../-.../.-/-.../.-/.-/.-/-.../-.../.-/.-/.-/-.../-.../.-/.-/-.../.-/.-/.-/.-/-.../.-/-.../.-/.-/-.../.-/.-/.-/-.../-.../.-/-.../.-/.-/.-/-.../.-/.-/.-/-.../.-/.-/-.../.-/-.../-.../.-/.-/-.../-.../-.../.-/-.../.-/.-/.-/-.../.-/-.../.-/-.../-.../.-/.-/.-/-.../-.../.-/-.../.-/.-/.-/-.../.-/.-/-.../.-/.-/-.../.-/.-/.-/.-/-.../-.../.-/-.../-.../.-/.-/-.../-.../.-/.-/-.../.-/.-/-.../.-/.-/.-/-.../.-/.-/-.../.-/.-/-.../.-/.-/-.../.-/-.../.-/.-/-.../-.../.-/-.../.-/.-/.-/.-/-.../-.../.-/-.../.-/.-/-.../-.../.-'
s2 = s1.replace('-', '1').replace('.', '0').replace('/', ' ')
print(s2)
#输出结果:
#11 01 1011 001101 1000 0 001101 0000 01 0001 0 001101 01 10 111 1 0000 0 010 001101 100 0 1010 111 100 0 0000 0000 0000 0000 01 01 01 01 01 1000 01 01 1000 1000 1000 01 01 1000 1000 01 01 01 01 01 01 01 01 1000 01 01 1000 01 1000 01 01 01 01 01 01 01 1000 1000 01 1000 01 01 01 1000 1000 01 01 01 1000 1000 01 01 1000 01 01 01 01 1000 01 1000 01 01 1000 01 01 01 1000 1000 01 1000 01 01 01 1000 01 01 01 1000 01 01 1000 01 1000 1000 01 01 1000 1000 1000 01 1000 01 01 01 1000 01 1000 01 1000 1000 01 01 01 1000 1000 01 1000 01 01 01 1000 01 01 1000 01 01 1000 01 01 01 01 1000 1000 01 1000 1000 01 01 1000 1000 01 01 1000 01 01 1000 01 01 01 1000 01 01 1000 01 01 1000 01 01 1000 01 1000 01 01 1000 1000 01 1000 01 01 01 01 1000 1000 01 1000 01 01 1000 1000 01

用在线网站解密:
MAY_BE_HAVE_ANOTHER_DECODEHHHHAAAAABAABBBAABBAAAAAAAABAABABAAAAAAABBABAAABBAAABBAABAAAABABAABAAABBABAAABAAABAABABBAABBBABAAABABABBAAABBABAAABAABAABAAAABBABBAABBAABAABAAABAABAABAABABAABBABAAAABBABAABBA

尝试解密H后面的内容
在某一篇博客里找到了:
CTF必备密码编码大全
培根密码:
培根密码(Baconian Cipher)是一种替换密码,每个明文字母被一个由5字符组成的序列替换,最初的加密方式就是由’A’和’B’组成序列替换明文(所以你当然也可以用别的字母),比如字母’D’替换成”aaabb”。
其实看起来也就是,a相当于0,b相当于1,然后在2^5内用二进制表示。
在这里插入图片描述

12. easy_RSA

题目:

#在一次RSA密钥对生成中,假设p=473398607161,q=4511491,e=17
#求解出d

解题脚本:

from Crypto.Util.number import inverse

p=473398607161
q=4511491
e=17

phi=(p-1)*(q-1)

d=inverse(e,phi)
print(d)

#125631357777427553

13. Normal_RSA

参考博客:
rsatool的使用。(提供enc和pem文件类)
不想下工具,这篇懒得写题解了,就看参考博客吧
浅更一下这题吧,还是要学一下的TT

———————————————————————————————————————
密码学第2篇:
攻防世界题目练习——Crypto密码新手+引导模式(二)(持续更新)

  • 11
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值