• ctf密码学常用python库


    1. pyCryptodome库

    pip3 install pyCryptodome -i https://pypi.douban.com/simple
    

    这个库是实现各种算法和协议的密码模块的集合,包含Cipher,Hash,Protocol,PublicKey,Signature,Util这些子包;

    1.1. Cipher子包

    实现了分组加密(AES,DES,DES3,CAST,Blowfish,RC2),流加密(RC4,XOR)与公钥加密(RSA PKCS#1与PKCS#1 OAEP,这两个区别在于加密前对数据的填充不同);如下是文档给出的例子:

    from Crypto.Cipher import AES
    from Crypto import Random
    key = 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

    from Crypto.PublicKey import RSA
    from Crypto.Cipher import PKCS1_v1_5
    from gmpy2 import invert
    from base64 import b64decode
    
    cip='bT633yPu4dOHEL66eKCHjg6cZb09CElt2mSSQZkRDHk='
    
    n=87924348264132406875276140514499937145050893665602592992418171647042491658461L
    e=65537L
    #http://factordb.com/
    p=275127860351348928173285174381581152299L
    q=319576316814478949870590164193048041239L
    phi=(p-1)*(q-1)
    d=invert(e,phi)
    
    privkey=RSA.construct((n,e,long(d),p,q))
    
    #原生RSA
    print privkey.decrypt(b64decode(cip))
    
    #PKCS#1填充
    key= PKCS1_v1_5.new(privkey)
    print key.decrypt(b64decode(cip),'')
    

    再举个OAEP填充的例子,加密的明文(字节)长度必须严格小于密钥(字节)长度减去41;你可以试一下在下面代码中的明文中多加一个字符运行就会报错。

    from Crypto.PublicKey import RSA
    from Crypto.Cipher import PKCS1_OAEP
    from base64 import b64encode,b64decode
    
    rsa_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 cip
    
    msg=key.decrypt(b64decode(cip))
    print msg
    

    1.2. Hash子包

    实现了哈希算法(MD2,MD4,MD5,RIPEMD,SHA,SHA224,SHA256,SHA384,SHA512,HMAC,hashalgo);如下是文档给出的例子:

    from Crypto.Hash import MD2
    h = MD2.new()
    h.update(b'Hello')
    print h.hexdigest()
    

    但是没有实现SHA1,要使用SHA1,需要导入hashlib库,正好验证一下Google之前给出的求得两个 sha1 值一样的pdf对:https://shattered.io/

    from hashlib import sha1
    
    with 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()
    

    1.3. PublicKey子包

    实现了公钥加密和签名算法(RSA,DSA,ElGamal);文档给出的例子:

    from Crypto.PublicKey import RSA
    key0 = 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())
    

    1.4. Util子包

    实现了各种有用的模块和功能(Util.number:数论函数,Util.randpool:随机数生成,Util.RFC1751:在128位键和可读的字串之间进行转换,Util.asn1:对ASN.1 DER编码的最小支持);自己写个例子如下:

    from Crypto.Util import number
    s='this is a demo'
    #字节转换为long型整数
    ls=number.bytes_to_long(s)
    
    bits=8*len(s)
    #生成长度为bits的素数
    gp=number.getPrime(bits)
    
    #生成长度小于bits的随机数
    gri=number.getRandomInteger(bits)
     
    #生成长度为bits的随机数
    grnbi=number.getRandomNBitInteger(bits)
     
    #生成长度不超过bits的随机数
    grn=number.getRandomNumber(bits)
     
    #生成grn与2*grn之间的随机数
    grr=number.getRandomRange(grn,2*grn)
    
    #生成强的素数(gsp-1,gsp+1均至少具有一个大的素因子)
    gsp=number.getStrongPrime(1024)
    
    #计算gri在模grn下的逆
    iin=number.inverse(gri,grn)
    
    #判断iin是否为素数
    ip=number.isPrime(iin)
    
    #long型整数转换为字节
    tb=number.long_to_bytes(ls)
    

    由于这个库很多函数都很有用,因此我们直接使用

    from Crypto.Util.number import *
    

    来导入这个包的所有函数。

    2. pwntools库

    pip3 install pwntools -i https://pypi.douban.com/simple
    

    这个库内容很多,只介绍比赛中用到的。

    2.1. 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指定穷举时的线程数,默认值是内核的数量;

    举个例子:

    from pwn import pwnlib
    from pwnlib.util.iters import mbruteforce
    mbruteforce(lambda x: x == 'hello','helo',5,method='fixed')
    

    2.2. remote类

    用来与服务器交互;常用函数的用法注释到如下脚本中。

    from pwn import pwnlib
    from pwnlib.tubes.remote import remote
    
    #创建到远程主机的TCP或udp连接,主机为cn.bing.com,连接主机的端口为443
    #ssl=True代表用SSL包装套接字
    r=remote('cn.bing.com',443,ssl=True)
    
    #向主机发送数据,只不过数据只能是一行
    r.sendline('GET /')
    
    #向主机发送数据,数据可以是多行
    r.send(b'
    
    ')
    
    ##上面两行代码等价于r.send(b'GET /
    
    ')
    
    #从主机接收4个字节的数据
    re=r.recvn(4)
    print re
    
    #从主机一直接收数据直到'Please'出现
    re=r.recvuntil('Please')
    print re
    
    #从主机一直接收数据,最多接收4096字节
    re=r.recv()
    print re
    
    #关闭连接
    r.close()
    
  • 相关阅读:
    文本每行都应该换行——vi文件末尾自动换行,不会导致php输出空行
    路由器 DNSMasq 替代 hosts,支持Android、iPhone、PC
    互联网创业的准备——web server:apache、nginx、lighttpd与php module、fastcgi
    dev qa prod
    互联网创业的准备——框架:从MVC到开放API
    Realtek 8192cu win8 驱动
    Win8 RTM 安装到 UEFI PC
    互联网创业的准备——数据库:硬盘iops、mysql
    互联网创业的准备——数据备份
    互联网创业的准备——依赖服务:云主机、域名、代码库
  • 原文地址:https://www.cnblogs.com/coming1890/p/13506932.html
Copyright © 2020-2023  润新知