Jason Sheh

使用pyOpenSSL为证书签名


0x00 起因
在编写代理扫描器的时候http代理很容易实现,然而不少代理也只实现了http,但是我不能只做http明显这是不足的。但要对https进行代理,就相当于对本机进行可控的中间人攻击,需要信任自己生成的CA并且用该CA签名生成证书。

0x01 生成CA
一下命令使用openssl执行
生成 CA 根密钥

openssl genrsa -out ./cakey.pem 2048

生成 CA 证书

openssl req -new -x509 -days 3650 -key ./cakey.pem -out ./cacert.pem

0x01 签发证书

def create_ca(host):
    cert_file = './cert/cacert.pem'
    key_file = './cert/cakey.pem'
    with open(cert_file, 'r') as my_cert_file:
        ca_cert = crypto.load_certificate(crypto.FILETYPE_PEM, my_cert_file.read())

    with open(key_file, 'r') as my_key_file:
        ca_key = crypto.load_privatekey(crypto.FILETYPE_PEM, my_key_file.read())

    # create a key pair
    key = crypto.PKey()
    key.generate_key(crypto.TYPE_RSA, 2048)

    # create a self-signed cert
    cert = crypto.X509()
    cert.get_subject().C = 'CN'
    cert.get_subject().ST = 'JiangSu'
    cert.get_subject().L = 'NanJing'
    cert.get_subject().O = 'ProxyScan'
    cert.get_subject().OU = 'ProxyScan CA'
    cert.get_subject().CN = host
    cert.set_serial_number(x509.random_serial_number())
    cert.gmtime_adj_notBefore(0)
    cert.gmtime_adj_notAfter(10 * 365 * 24 * 60 * 60)

    cert.set_issuer(ca_cert.get_subject())
    cert.set_pubkey(key)
    cert.sign(ca_key, "sha256")

    open("./cert/website/"+host.strip('')+".cert.pem", "wt").write(
    crypto.dump_certificate(crypto.FILETYPE_PEM, cert).decode())
    open("./cert/website/"+host.strip('')+".key.pem", "wt").write(
    crypto.dump_privatekey(crypto.FILETYPE_PEM, key).decode())

需要注意的是在参考docs.genati.org时,有一处错误crypto.dump_certificate()和crypto.dump_privatekey()传入的参数应该是文件而不是路径

此外sha1算法不足够安全需要使用sha256