使用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

发表评论

电子邮件地址不会被公开。 必填项已用*标注