Crypto

看了《密码编码学与网络安全》的大部分内容,首先做了攻防世界网站里面的新手题目,对它考查的内容有了初步的认识,有加密和编码的内容,加密包含了几种密码:栅栏密码,摩斯密码,RSA密码,轮转机,培根密码等
编码包括:BASE64(6个bit组成一个字符,共有64种字符)Unicode ,ASCII

学习到的Crypto所需工具

最好在kali环境下完成,RSA密码使用opensll以及代码版的RSATools
编码的话收集到了许多转换工具,这里也不一一赘述,比较好用的工具叫 convertor

openssl的RSA解密过程

这种题目一般会给你一个.enc文件(被加密过的flag文件)还有一个.pem文件(公钥文件)
在Kali系统的terminal中使用OpenSSL执行openssl rsa -pubin -in pubkey.pem -text -modulus,即可看到该pem文件内的公钥e和模数n,接着在质数分解网站分解这个模数得到p和q两个质数,之后可以使用exe版的RSAtool得出私钥d。
如果是要求我们解密enc文件的话,我们需要使用python版的rsatools获得私钥的pem文件,执行以下命令:

python3 rsatool.py -f PEM -o private.pem -p Value_p -q Value_q -e Value_e

我们就获得了一个private.pem的私钥文件,之后再执行以下命令:

openssl rsautl -decrypt -in flag.enc -inkey private.pem -out flag.dec

我们就能得到一个flag.dec文件,里面就是解密得到的字符了。

RSA中的攻击方式

  1. 共模攻击
  2. 低指数/高指数攻击
  3. 中国余数定理/广播攻击
  4. 低指数(相比2而言,指数已经比较高了),密文间有线性关系,也可以进行攻击

XCTF的轮转机解密

Wheel Cipher
加密表:
1: < ZWAXJGDLUBVIQHKYPNTCRMOSFE <
2: < KPBELNACZDTRXMJQOYHGVSFUWI <
3: < BDMAIZVRNSJUWFHTEQGYXPLOCK <
4: < RPLNDVHGFCUKTEBSXQYIZMJWAO <
5: < IHFRLABEUOTSGJVDKCPMNZQWXY <
6: < AMKGHIWPNYCJBFZDRUSLOQXVET <
7: < GWTHSPYBXIZULVKMRAFDCEONJQ <
8: < NOZUTWDCVRJLXKISEFAPMYGHBQ <
9: < XPLTDSRFHENYVUBMCQWAOIKZGJ <
10: < UDNAJFBOWTGVRSCZQKELMXYIHP <
11: < MNBVCXZQWERTPOIUYALSKDJFHG <
12: < LVNCMXZPQOWEIURYTASBKJDFHG <
13: < JZQAWSXCDERFVBGTYHNUMKILOP <

密钥为:2,3,7,5,13,12,9,1,8,10,4,11,6
密文为:NFQKSEVOQOFNP

既然是车轮,看来需要轮换,一开始以为是将密文对应密钥位置进行替换,发现不对,查了查发现Jefferson wheel cipher(杰弗逊转轮加密器),差不多重新排一下序,并把密文转到第一个位置,发现flag:FIREINTHEHOLE

一些奇奇怪怪的加密或编码方法

BrainFuck和OOK!编码:一个好心人的解码链接
猪圈密码,培根密码,标准银河字母的编码,佛箴言密码,云影密码
一个很全的集合

python相关知识

熟悉python的base64库内的各种decode和encode,chr和ord是两对互补的函数
以及python中调用Crypto中的AES加密等操作

11.21更新:

关于sage:sage是一个相当全面的数学工具,第三届红帽杯和其他大大小小比赛都有相关的sage写的题目。
这里介绍红帽杯中的Related一题,题目大致是,三个不同的明文通过RSA加密后的密文已知,公钥也已知,同时三个明文的和也已知,其实上述这些条件已经可以解出答案了,但是题目还给出了两个无关的信息,这是我觉得题目可能要混淆人的地方,总结下来,就是解答下面这个方程组:
x 0 + x 1 + x 2 − s ≡ 0 m o d    N x 0 17 − c 0 ≡ 0 m o d    N x 1 1 7 − c 1 ≡ 0 m o d    N x 2 1 7 − c 2 ≡ 0 m o d    N x_0+x_1+x_2-s \equiv 0\mod N\\ x_0^{17}-c_0 \equiv 0\mod N\\ x_1^17-c_1 \equiv 0\mod N\\ x_2^17-c_2 \equiv 0\mod N x0+x1+x2s0modNx017c00modNx117c10modNx217c20modN
当中 x 0 , x 1 , x 2 x_0,x_1,x_2 x0,x1,x2未知,其余已知,查阅文献找到一篇名为< Low-Exponent RSA with Related Messages >的论文,解决这个问题的关键就是找到Groebner basis,当然这个问题在sage中很好解决,只要构建一个mod N的有三个变量的多项式环,用上述的多项式构建一个Ideal(理想),然后用sage中的groebner_basis函数即可简化多项式求出 x 0 , x 1 , x 2 x_0,x_1,x_2 x0,x1,x2的值,具体是怎么求得呢,是一个叫做buchberger的算法,具体参考书籍< Ideals, Varieties, and Algorithms (4th ed.) [Cox, Little & O’Shea 2015-06-14] >文中有很详细的介绍,官方writeup如下:

#!/usr/bin/sage -python
from Crypto.Util import number
from sage.all import *


N = 16084923760264169099484353317952979348361855860935256157402027983349457021767614332173154044206967015252105109115289920685657394517879177103414348487477378025259589760996270909325371731433876289897874303733424115117776042592359041482059737708721396118254756778152435821692154824236881182156000806958403005506732891823555324800528934757672719379501318525189471726279397236710401497352477683714139039769105043411654493442696289499967521222951945823233371845110807469944602345293068346574630273539870116158817556523565199093874587097230314166365220290730937380983228599414137341498205967870181640370981402627360812251649
Cs = [10607235400098586699994392584841806592000660816191315008947917773605476365884572056544621466807636237415893192966935651590312237598366247520986667580174438232591692369894702423377081613821241343307094343575042030793564118302488401888197517625333923710172738913771484628557310164974384462856047065486913046647133386246976457961265115349103039946802386897315176633274295410371986422039106745216230401123542863714301114753239888820442112538285194875243192862692290859625788686421276234445677411280606266052059579743874849594812733193363406594409214632722438592376518310171297234081555028727538951934761726878443311071990L, 2665348075952836665455323350891842781938471372943896177948046901127648217780657532963063228780230203325378931053293617434754585479452556620021360669764370971665619743473463613391689402725053682169256850873752706252379747752552015341379702582040497607180172854652311649467878714425698676142212588380080361100526614423533767196749274741380258842904968147508033091819979042560336703564128279527380969385330845759998657540777339113519036552454829323666242269607225156846084705957131127720351868483375138773025602253783595007177712673092409157674720974653789039702431795168654387038080256838321255342848782705785524911705L, 4881225713895414151830685259288740981424662400248897086365166643853409947818654509692299250960938511400178276416929668757746679501254041354795468626916196040017280791985239849062273782179873724736552198083211250561192059448730545500442981534768431023858984817288359193663144417753847196868565476919041282010484259630583394963580424358743754334956833598351424515229883148081492471874232555456362089023976929766530371320876651940855297249474438564801349160584279330339012464716197806221216765180154233949297999618011342678854874769762792918534509941727751433687189532019000334342211838299512315478903418642056097679717L, 12534425973458061280573013378054836248888335198966169076118474130362704619767247747943108676623695140384169222126709673116428645230760767457471129655666350250668322899568073246541508846438634287249068036901665547893655280767196856844375628177381351311387888843222307448227990714678010579304867547658489581752103225573979257011139236972130825730306713287107974773306076630024338081124142200612113688850435053038506912906079973403207309246156198371852177700671999937121772761984895354214794816482109585409321157303512805923676416467315573673701738450569247679912197730245013539724493780184952584813891739837153776754362L]
s = 280513550110197745829890567436265496990

e = 17
l = len(Cs)
PR = PolynomialRing( Zmod(N), 'x', l )
x = PR.gens()
f1 = (65537*x[0] - 66666*x[1] + 12345*x[2] - x[3])
f2 = x[0] + x[1] + x[2] - s
Fs = [f1, f2]
Fs.extend( [ (x[i]**e - Cs[i]) for i in range(l) ] )
I = Ideal(Fs)
B = I.groebner_basis()
m = ''
for b in B[:-1][::-1]:
    assert b.degree() == 1
    mi = ZZ( -b(0,0,0,0) )
    m += number.long_to_bytes(mi)
print m

其实,这个代码是可以简化的,如下:

#!/usr/bin/sage -python
from Crypto.Util import number
from sage.all import *


N = 16084923760264169099484353317952979348361855860935256157402027983349457021767614332173154044206967015252105109115289920685657394517879177103414348487477378025259589760996270909325371731433876289897874303733424115117776042592359041482059737708721396118254756778152435821692154824236881182156000806958403005506732891823555324800528934757672719379501318525189471726279397236710401497352477683714139039769105043411654493442696289499967521222951945823233371845110807469944602345293068346574630273539870116158817556523565199093874587097230314166365220290730937380983228599414137341498205967870181640370981402627360812251649
Cs = [10607235400098586699994392584841806592000660816191315008947917773605476365884572056544621466807636237415893192966935651590312237598366247520986667580174438232591692369894702423377081613821241343307094343575042030793564118302488401888197517625333923710172738913771484628557310164974384462856047065486913046647133386246976457961265115349103039946802386897315176633274295410371986422039106745216230401123542863714301114753239888820442112538285194875243192862692290859625788686421276234445677411280606266052059579743874849594812733193363406594409214632722438592376518310171297234081555028727538951934761726878443311071990L, 2665348075952836665455323350891842781938471372943896177948046901127648217780657532963063228780230203325378931053293617434754585479452556620021360669764370971665619743473463613391689402725053682169256850873752706252379747752552015341379702582040497607180172854652311649467878714425698676142212588380080361100526614423533767196749274741380258842904968147508033091819979042560336703564128279527380969385330845759998657540777339113519036552454829323666242269607225156846084705957131127720351868483375138773025602253783595007177712673092409157674720974653789039702431795168654387038080256838321255342848782705785524911705L, 4881225713895414151830685259288740981424662400248897086365166643853409947818654509692299250960938511400178276416929668757746679501254041354795468626916196040017280791985239849062273782179873724736552198083211250561192059448730545500442981534768431023858984817288359193663144417753847196868565476919041282010484259630583394963580424358743754334956833598351424515229883148081492471874232555456362089023976929766530371320876651940855297249474438564801349160584279330339012464716197806221216765180154233949297999618011342678854874769762792918534509941727751433687189532019000334342211838299512315478903418642056097679717L, 12534425973458061280573013378054836248888335198966169076118474130362704619767247747943108676623695140384169222126709673116428645230760767457471129655666350250668322899568073246541508846438634287249068036901665547893655280767196856844375628177381351311387888843222307448227990714678010579304867547658489581752103225573979257011139236972130825730306713287107974773306076630024338081124142200612113688850435053038506912906079973403207309246156198371852177700671999937121772761984895354214794816482109585409321157303512805923676416467315573673701738450569247679912197730245013539724493780184952584813891739837153776754362L]
s = 280513550110197745829890567436265496990

e = 17
l = 3
PR = PolynomialRing( Zmod(N), 'x', l )
x = PR.gens()
#f1 = (65537*x[0] - 66666*x[1] + 12345*x[2] - x[3])#其实就是这里的x[3]没必要解出来,感觉出题人就是在混淆视听
f2 = x[0] + x[1] + x[2] - s
Fs = [f2]
Fs.extend( [ (x[i]**e - Cs[i]) for i in range(l) ] )
I = Ideal(Fs)
B = I.groebner_basis()
m = ''
for b in B[::-1]:
    assert b.degree() == 1
    mi = ZZ( -b(0,0,0) )
    m += number.long_to_bytes(mi)
print m

sage中,term(项)和monomial(单项式)是不同的的,类Polynomial中有两个函数可以分别得到leading term和leading monomial(leading的意思可以在书中找到),这里主要说明一下term是带coefficient的monomial,如term是 2 x 2 2x^2 2x2而相应的monomial是 x 2 x^2 x2

R G ( x 1 d ) = x n d n R_G(x_1^d)=x_n^{d^n} RG(x1d)=xndn

小总结

Crypto的题目千变万化,还有其他许多类型,接下来应该具体参考CTFWiki之类的网站还有实际做题了

更多推荐

CTF之Crypto新手入门