月饼杯2020_Crypto

复现比赛系列;希望对大家学习密码学有所帮助

crypto1_中秋月

题目描述:

fsskryenvkm~jl{ejs}jwflzsnpgmifq{{j{|suhzrjppnx|qvixt~whu

hint:

经此古典密码加密后,密文还是大写

该古典密码的密钥形式:
keyword+plaintext (+plaintext…+plaintext)

自动钥匙⊕

显然是自动密钥加密没错了

但是需要注意到这里给出的密文并不是这种加密得到的密文(应该是大写的)

可能经过了某种变换;

题目中还有⊕;可能是异或

使用cyberchief试一试异或(cyberchief的异或选项有爆破功能)

得到一种情况恰好全部为大写字母:

YLLTMFZQITRAUSDZULBUHYSELQOXRVYNDDUDCLJWEMUOOQGCNIVGKAHWJ5

github上搜到自动密钥解密的脚本break_autokeyGitHub - hitcxy/break_autokey

修改一下脚本(因为我是python3的)运行得到flag

flag:

flag{do_you_like_classical_cipher}

crypto2_月自圆

题目:

# -*- coding:utf-8 -*-
#Author: Lazzaro

from itertools import *
from random import *
from string import *

def encrypt(m, a, si):
	c=""
	for i in range(len(m)):
		c+=hex(((ord(m[i])) * a + ord(next(si))) % 128)[2:].zfill(2)
	return c
	
if __name__ == "__main__":
	m = '****************************************************flag{*************}'
	assert(len(m)==71)
	a = randint(50,100)
	salt = ''.join(sample(ascii_uppercase, 4))
	si = cycle(salt.lower())
	c=encrypt(m, a, si)
	print(c)
	
#3472184e657e50561c481f5c1c4e1938163e154431015e13062c1b073d4e3a444f4a5c5c7a071919167b034e1c29566647600c4e1c2956661b6c1f50622f0016317e563546202a

程序逻辑:

随机生成盐值和一个整数用于加密;

salt生成迭代对象,可以无限循环salt本身的字符;

cycle()函数的作用

用**cycle()**循环迭代,**cycle()**函数重复循环一组值,可用它循环数据集标识符对数据集进行分组

sample(序列a,n):

在从序列a中随机抽取n个元素,并将n个元素生以list形式返回。

所以实际上每次进行encrypto()函数加密盐值的只有一个字符

而a的值很小,可以一起爆破

明文中给出了部分“flag”;在密文中可以对照的找到“flag”对应的密文是1c295666”

可以对照这段字符进行爆破:看加密之后是否于密文相同;注意是需要单个字符分别爆破;

因为每次加密取得是单个字符而且si在每几次加密中可能是不同字符的(假设salt = “aes”,那么第一次加密就是si=“a”,第二次加密si = “e”,以此类推)

爆破出各个字符满足的a,进行对比可以找到唯一满足情况的a

然后爆破salt,还是代入encrypto()函数进行把爆破,看密文是否对应,需要爆破"flag{"

因为不确定salt的大小;结果爆破出来:“JESQJ”

猜测应该是salt = “JESQ”

这样就可以求解flag了,还是运用爆破明文字符(可打印字符范围);需要注意每次爆破出一个明文字符,si的值需要换到下一个,而next()函数的传参不能是非对象的,所以这里另外创建一个中间量sii,而在encrpto()函数中把next()函数去掉

代码实现:

from string import *
from random import *
from itertools import *

c = "3472184e657e50561c481f5c1c4e1938163e154431015e13062c1b073d4e3a444f4a5c5c7a071919167b034e1c29566647600c4e1c2956661b6c1f50622f0016317e563546202a"
def encrypt(m, a, si):
	c=""
	for i in range(len(m)):
		c+=hex(((ord(m[i])) * a + ord(next(si))) % 128)[2:].zfill(2)
	return c

def encrypt2(m, a, si):
	c=""
	for i in range(len(m)):
		c+=hex(((ord(m[i])) * a + ord(si)) % 128)[2:].zfill(2)
	return c
#for语句中的if语句需要分别使用,同时运行的话因为si的值固定所以无法正确爆破
# for a in range(50,100):
#     for j in ascii_uppercase:
#         si = cycle(j.lower())
        # if encrypt("f",a,si) == "1c":
        #     print("f:",end="")
        #     print(a,j)
        # if encrypt("l",a,si) == "29":
        #     print("l:",end="")
        #     print(a,j)
        # if encrypt("a",a,si) == "56":
        #     print("a:",end="")
        #     print(a,j)
#"fla"爆破对比a = 67
# for j in ascii_uppercase:
#     si = cycle(j.lower())
    # if encrypt("f",67,si) == "1c":
    #     print(j)
    # if encrypt("l",67,si) == "29":
    #     print(j)    
    # if encrypt("a",67,si) == "56":
    #     print(j)
    # if encrypt("g",67,si) == "66":
    #     print(j)
#"flag"爆破salt得到JESQ
salt = "JESQ"
a = 67
si = cycle(salt.lower())
for i in range(0,len(c),2):
    temp = c[i:i+2]
    sii = next(si)
    for j in range(32,127):
        temp2 = encrypt2(chr(j),a,sii)
        if temp == temp2:
            print(chr(j),end="")
# now_is_7fad9fcb-d361-4964-821c-177c906b8d20_flag_is_flag{md5(now-salt)}
import hashlib
flag = "7fad9fcb-d361-4964-821c-177c906b8d20-JESQ" #这里太🐕了,后面加上"-JESQ"是真的有点考理解
print("")
print(hashlib.md5(flag.encode("utf8")).hexdigest())

crypto3_多少离怀

题目:

# -*- coding:utf-8 -*-
#Author: Lazzaro

from Crypto.Util.number import getPrime,isPrime
from math import gamma
import random

def nextPrime(n):
    n += 2 if n & 1 else 1
    while not isPrime(n):
        n += 2
    return n

def getNewPrime():
    A = getPrime(512)
    B = nextPrime(A - random.randint(1e4,1e5))
    return nextPrime(gamma(B+2)%A)
	
p = getNewPrime()
q = getNewPrime()
r = getNewPrime()
n = p * q ** 2 * r ** 3
e = 0x10001
c = pow(flag,e,n)


#pA=6814157460586876042804041951834304833424062437744287469257313954502540797027261340622077218188033865281590529907571701131297782609357118357982463723982789
#pB=6814157460586876042804041951834304833424062437744287469257313954502540797027261340622077218188033865281590529907571701131297782609357118357982463723922147
#qA=7145646366857234331692232566211321498245533826533958883943688415057871253511271731661019642050252046201115975396366275083424623329930477623781348477881291
#qB=7145646366857234331692232566211321498245533826533958883943688415057871253511271731661019642050252046201115975396366275083424623329930477623781348477807457
#n=4451906216583258787166698210560165433649728830889954633721198623488802305844782492171757604711145165920462286487680020347239300947225371917344589502941576734875830871998499135120227347066586066943289430156378296665669974728569678779668142712266780949126509440672273927433367293606776081254094682033167575930701870261219046464773708974194213798032346187463443317770758989273370488582862531630356263732232300508706676725203199729764016766683870925164232508407363688370458877688991733322055785233669885166225464068579486683574954699370175267031949720967812902215635630884502987094547523361027411501285252862476410213277925430392164226297316310465146003494714018456407793759170649913180823814850170639706664167149612984905056804131124522209409607977589884632999710708045656852149371030046919242039957767777840304466948549383597755811307383659188216421501912831203089570725388153416013596114462069777713822433178099904907224119
#c=1996198968748552041728429851810599627895157160099076033250854211280074825148767841655949210593646824507865483166496070951130337321360509148527292165245205219296211294789087358959553387392928560150390604911087085313000622842025416521494799132969818997182731021267942464323979261593380113740152841984062184326431879167516288834455296913822921806893572566867611541664848820247889274979245086440402996661226884320574824077910315143756471444347386795428338020162169391827182914043434253974549636668126789355991920452920806351939782281969098470635517019120996509180703896707990501216102290302162705699788457579330150149320348175742131887213742989509004374645723471497302400169849858253644606818874098604333865973357374444445825761600866472906771935670261641342221394488068630591190697667016958881530367047928341661857241378511420562236766886349565409774340321441504290366223243635878057759623855735794209219474650425139791831374

hint:

注意伽马函数Γ(x)和阶乘x!的关系式

威尔逊定理

逻辑很简单:

随机生成素数pA,将pA减去一个随机在1e4到1e5之间的整数的下一个素数得到pB

素因子p = gamma(pB+2)%pA;同理q

而题目已给出pA,pB,qA,qB

错误示范:

原始想法:按着加密的算法再算一遍就好了啊,直接可以求得p和q

但是运行过程得到报错:math range error

搜一搜gamma函数;再结合hint和大佬wp;

g a m m a ( n ) = ( n − 1 ) ! gamma(n) = (n-1)! gamma(n)=(n1)!

威尔逊定理:

( p − 1 ) ! = − 1   ( m o d   p ) (p-1)!=-1~(mod~p) (p1)!=1 (mod p)

( p − 2 ) ! = 1   ( m o d   p ) (p-2)!=1~(mod~p) (p2)!=1 (mod p)

而题目中最后pq是等于 g a m m a ( p B + 2 )   %   p A gamma(pB+2)~\%~pA gamma(pB+2) % pA

也就相当于 ( p B + 1 ) !   %   p A (pB+1)!~\%~pA (pB+1)! % pA

既然有求余符号就尽量往同余1的方向带

构造这样的同余式:

( p A − 2 ) ! / ( p B + 2 ) ! ∗ ( p B + 2 ) ! ≡ 1   ( m o d   p A ) (pA-2)!/(pB+2)!*(pB+2)!\equiv1~(mod~pA) (pA2)!/(pB+2)!(pB+2)!1 (mod pA)

x = ( p A − 2 ) ! / ( p B + 2 ) ! x = (pA-2)!/(pB+2)! x=(pA2)!/(pB+2)! y = ( p B + 2 ) ! y = (pB+2)! y=(pB+2)!

要求的y的大小;也就是求x与模数pA的逆元

p A − 2 pA-2 pA2 p B + 2 pB+2 pB+2相差 1 e 4 1e4 1e4 1 e 5 1e5 1e5之间

他们两者相除得到:

p B ∗ ( p A − 2 − p B ) ∗ . . . ∗ ( p A − 2 ) pB*(pA-2-pB)*...*(pA-2) pB(pA2pB)...(pA2)

使用封装函数gmpy2.invert()即可求得逆元

注意这里遍历的时候需要每一个遍历量先进行求逆元;因为这样的阶乘还是太大了,中间如果有求余过程的话会简化很多计算过程

得到逆元也就是得到p和q;之后算r;使用 n / / p / / q 2 n//p//q^2 n//p//q2

算fai_n的时候需要注意素因子的次方情况下,欧拉函数等于 ( p n − p n − 1 ) (p^n-p^{n-1}) (pnpn1)

代码实现:

import gmpy2
from Crypto.Util.number import *
from sympy.ntheory.generate import nextprime

pA = 6814157460586876042804041951834304833424062437744287469257313954502540797027261340622077218188033865281590529907571701131297782609357118357982463723982789
pB = 6814157460586876042804041951834304833424062437744287469257313954502540797027261340622077218188033865281590529907571701131297782609357118357982463723922147
qA = 7145646366857234331692232566211321498245533826533958883943688415057871253511271731661019642050252046201115975396366275083424623329930477623781348477881291
qB = 7145646366857234331692232566211321498245533826533958883943688415057871253511271731661019642050252046201115975396366275083424623329930477623781348477807457
n = 4451906216583258787166698210560165433649728830889954633721198623488802305844782492171757604711145165920462286487680020347239300947225371917344589502941576734875830871998499135120227347066586066943289430156378296665669974728569678779668142712266780949126509440672273927433367293606776081254094682033167575930701870261219046464773708974194213798032346187463443317770758989273370488582862531630356263732232300508706676725203199729764016766683870925164232508407363688370458877688991733322055785233669885166225464068579486683574954699370175267031949720967812902215635630884502987094547523361027411501285252862476410213277925430392164226297316310465146003494714018456407793759170649913180823814850170639706664167149612984905056804131124522209409607977589884632999710708045656852149371030046919242039957767777840304466948549383597755811307383659188216421501912831203089570725388153416013596114462069777713822433178099904907224119
c = 1996198968748552041728429851810599627895157160099076033250854211280074825148767841655949210593646824507865483166496070951130337321360509148527292165245205219296211294789087358959553387392928560150390604911087085313000622842025416521494799132969818997182731021267942464323979261593380113740152841984062184326431879167516288834455296913822921806893572566867611541664848820247889274979245086440402996661226884320574824077910315143756471444347386795428338020162169391827182914043434253974549636668126789355991920452920806351939782281969098470635517019120996509180703896707990501216102290302162705699788457579330150149320348175742131887213742989509004374645723471497302400169849858253644606818874098604333865973357374444445825761600866472906771935670261641342221394488068630591190697667016958881530367047928341661857241378511420562236766886349565409774340321441504290366223243635878057759623855735794209219474650425139791831374
e = 65537
#注释部分是错误示范

#由于math range error;得到的数字超过了数学范围,不能这样直接求解
# p = sympy.nextprime(gamma(pB+2)%pA)
# print(p)

#由于pA,pB太大了,无法求阶乘
# jiec1 = 1
# jiec2 = 1
# for i in range(1,pA - 2):
#     jiec1 *= i
# for i in range(1,pB + 1):
#     jiec2 *= i 
# x = jiec1 // jiec2
# y = gmpy2.invert(x,pA)

def getrealprime(a,b):
    difference = a - 2 - (b + 1)
    temp = 1
    for i in range(0,difference):
        temp = temp * gmpy2.invert(a-2-i,a) % a
    return nextprime(temp)
p = getrealprime(pA,pB)
print(p)
q = getrealprime(qA,qB)
print(q)
r = gmpy2.iroot(n // p // q**2,3)[0]
fai_n = (p-1)*(q-1)*q*(r-1)*r**2
d = gmpy2.invert(e,fai_n)
m = pow(c,d,n)
print(long_to_bytes(m))

这是解题过程中借鉴的大佬wp:https://blog.csdn.net/hiahiachang/article/details/108800210
https://blog.csdn.net/Kr0ne/article/details/108833373?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522163503761916780366522347%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=163503761916780366522347&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_ecpm_v1~rank_v31_ecpm-3-108833373.first_rank_v2_pc_rank_v29&utm_term=ctfshow+%E6%9C%88%E9%A5%BC%E6%9D%AF2020&spm=1018.2226.3001.4187

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

M3ng@L

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值