pyCryptodome库 1 pip3 install pyCryptodome -i https://pypi.douban.com/simple
这个库是实现各种算法和协议的密码模块的集合,包含Cipher,Hash,Protocol,PublicKey,Signature,Util这些子包;
Cipher子包 实现了分组加密(AES,DES,DES3,CAST,Blowfish,RC2),流加密(RC4,XOR)与公钥加密(RSA PKCS#1与PKCS#1 OAEP,这两个区别在于加密前对数据的填充不同);如下是文档给出的例子:
1 2 3 4 5 6 7 from Crypto.Cipher import AESfrom Crypto import Randomkey = b'Sixteen byte key' iv = Random.new().read(AES.block_size) cipher = AES.new(key, AES.MODE_CFB, iv) msg = iv + cipher.encrypt(b'Attack at dawn' ) print msg.encode('hex' )
有时在解RSA的题时,已经知道了密钥,解出来的flag却是乱码,也许是加了一些填充如OAEP,PKCS#1导致的;这时就需要使用对应的秘钥解密;如下是一个PKCS#1填充的例子,加密的明文(字节)长度必须严格小于密钥(字节)长度-11
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 from Crypto.PublicKey import RSAfrom Crypto.Cipher import PKCS1_v1_5from gmpy2 import invertfrom base64 import b64decodecip='bT633yPu4dOHEL66eKCHjg6cZb09CElt2mSSQZkRDHk=' n=87924348264132406875276140514499937145050893665602592992418171647042491658461L e=65537L p=275127860351348928173285174381581152299L q=319576316814478949870590164193048041239L phi=(p-1 )*(q-1 ) d=invert(e,phi) privkey=RSA.construct((n,e,long(d),p,q)) print privkey.decrypt(b64decode(cip))key= PKCS1_v1_5.new(privkey) print key.decrypt(b64decode(cip),'' )
再举个OAEP填充的例子,加密的明文(字节)长度必须严格小于密钥(字节)长度减去41;你可以试一下在下面代码中的明文中多加一个字符运行就会报错。
1 2 3 4 5 6 7 8 9 10 11 from Crypto.PublicKey import RSAfrom Crypto.Cipher import PKCS1_OAEPfrom base64 import b64encode,b64decodersa_key=RSA.generate(1024 ) key=PKCS1_OAEP.new(rsa_key) cip=b64encode(key.encrypt('PCTF{256b_i5_m3dium}PCTF{256b_i5_m3dium}PCTF{256b_i5_m3dium}PCTF{256b_i5_m3dium}abcdef' )) print cipmsg=key.decrypt(b64decode(cip)) print msg
Hash子包 实现了哈希算法(MD2,MD4,MD5,RIPEMD,SHA,SHA224,SHA256,SHA384,SHA512,HMAC,hashalgo);如下是文档给出的例子:
1 2 3 4 from Crypto.Hash import MD2h = MD2.new() h.update(b'Hello' ) print h.hexdigest()
但是没有实现SHA1,要使用SHA1,需要导入hashlib库,正好验证一下Google之前给出的求得两个 sha1 值一样的pdf对:https://shattered.io/
1 2 3 4 5 6 7 8 9 from hashlib import sha1with open ('shattered-1.pdf' ,'rb' ) as f1: da1=f1.read() with open ('shattered-2.pdf' ,'rb' ) as f2: da2=f2.read() print sha1(da1).hexdigest()print sha1(da2).hexdigest()
PublicKey子包 实现了公钥加密和签名算法(RSA,DSA,ElGamal);文档给出的例子:
1 2 3 4 5 6 7 from Crypto.PublicKey import RSAkey0 = RSA.generate(2048 ) with open ('mykey.pem' ,'w' ) as f: f.write(key0.exportKey('PEM' )) with open ('mykey.pem' ,'r' ) as g: key = RSA.importKey(g.read())
Util子包 实现了各种有用的模块和功能(Util.number:数论函数,Util.randpool:随机数生成,Util.RFC1751:在128位键和可读的字串之间进行转换,Util.asn1:对ASN.1 DER编码的最小支持);自己写个例子如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 from Crypto.Util import numbers='this is a demo' ls=number.bytes_to_long(s) bits=8 *len (s) gp=number.getPrime(bits) gri=number.getRandomInteger(bits) grnbi=number.getRandomNBitInteger(bits) grn=number.getRandomNumber(bits) grr=number.getRandomRange(grn,2 *grn) gsp=number.getStrongPrime(1024 ) iin=number.inverse(gri,grn) ip=number.isPrime(iin) tb=number.long_to_bytes(ls)
由于这个库很多函数都很有用,因此我们直接使用1 from Crypto.Util.number import *
来导入这个包的所有函数。
pwntools库 1 pip3 install pwntools -i https://pypi.douban.com/simple
这个库内容很多,只介绍比赛中用到的。
mbruteforce函数 多线程穷举函数,详细定义如下:mbruteforce(func, alphabet, length, method=’upto’, start=None, threads=None),其中,
func输入参数为字符串,输出布尔值,mbruteforce穷举直到func输出True;
alphabet为组成输入参数字符串的字符集合;
length指定输入参数字符串的长度上界;
method默认为’upto’,指定穷举的字符串长度从1增大到length;另外两个选项为’fixed’、’downfrom’,fixed’指定穷举的字符串长度仅为ength,’downfrom’指定穷举的字符串长度从length减小到1;
start=(N,i),就是把搜索空间分成N块从第i块开始穷举;默认为(1,1)
threads指定穷举时的线程数,默认值是内核的数量;
举个例子:
1 2 3 from pwn import pwnlibfrom pwnlib.util.iters import mbruteforcembruteforce(lambda x: x == 'hello' ,'helo' ,5 ,method='fixed' )
remote类 用来与服务器交互;常用函数的用法注释到如下脚本中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 from pwn import pwnlibfrom pwnlib.tubes.remote import remoter=remote('cn.bing.com' ,443 ,ssl=True ) r.sendline('GET /' ) r.send(b'\r\n\r\n' ) re=r.recvn(4 ) print rere=r.recvuntil('Please' ) print rere=r.recv() print rer.close()