为你的微服务架构或者集成测试创建一个简单的内部 CA。
传输层安全(TLS )模型(有时也称它的旧名称 SSL)基于 证书颁发机构 certificate authoritie (CA)的概念。这些机构受到浏览器和操作系统的信任,从而签名 服务器的的证书以用于验证其所有权。
但是,对于内部网络,微服务架构或集成测试,有时候本地 CA 更有用:一个只在内部受信任的 CA,然后签名本地服务器的证书。
这对集成测试特别有意义。获取证书可能会带来负担,因为这会占用服务器几分钟。但是在代码中使用“忽略证书”可能会被引入到生产环境,从而导致安全灾难。
CA 证书与常规服务器证书没有太大区别。重要的是它被本地代码信任。例如,在 Python requests
库中,可以通过将 REQUESTS_CA_BUNDLE
变量设置为包含此证书的目录来完成。
在为集成测试创建证书的例子中,不需要长期的 证书:如果你的集成测试需要超过一天,那么你应该已经测试失败了。
因此,计算昨天 和明天 作为有效期间隔:
1 2 3 4 5 >>> import datetime>>> one_day = datetime.timedelta(days=1 ) >>> today = datetime.date.today() >>> yesterday = today - one_day >>> tomorrow = today - one_day
现在你已准备好创建一个简单的 CA 证书。你需要生成私钥,创建公钥,设置 CA 的“参数”,然后自签名证书:CA 证书总是 自签名的。最后,导出证书文件以及私钥文件。
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 33 34 35 36 37 38 39 40 from cryptography.hazmat.primitives.asymmetric import rsafrom cryptography.hazmat.primitives import hashes, serializationfrom cryptography import x509from cryptography.x509.oid import NameOID private_key = rsa.generate_private_key( public_exponent =65537, key_size =2048, backend =default_backend() ) public_key = private_key.public_key() builder = x509.CertificateBuilder() builder = builder.subject_name(x509.Name([ x509.NameAttribute(NameOID.COMMON_NAME, 'Simple Test CA' ), ])) builder = builder.issuer_name(x509.Name([ x509.NameAttribute(NameOID.COMMON_NAME, 'Simple Test CA' ), ])) builder = builder.not_valid_before(yesterday) builder = builder.not_valid_after(tomorrow) builder = builder.serial_number(x509.random_serial_number()) builder = builder.public_key(public_key) builder = builder.add_extension( x509.BasicConstraints(ca =True , path_length =None), critical =True ) certificate = builder.sign( private_key =private_key, algorithm =hashes.SHA256(), backend =default_backend() ) private_bytes = private_key.private_bytes( encoding =serialization.Encoding.PEM, format =serialization.PrivateFormat.TraditionalOpenSSL, encryption_algorithm =serialization.NoEncrption()) public_bytes = certificate.public_bytes( encoding =serialization.Encoding.PEM) with open("ca.pem" , "wb" ) as fout: fout.write(private_bytes + public_bytes) with open("ca.crt" , "wb" ) as fout: fout.write(public_bytes)
通常,真正的 CA 会需要证书签名请求 (CSR)来签名证书。但是,当你是自己的 CA 时,你可以制定自己的规则!可以径直签名你想要的内容。
继续集成测试的例子,你可以创建私钥并立即签名相应的公钥。注意 COMMON_NAME
需要是 https
URL 中的“服务器名称”。如果你已配置名称查询,你需要服务器能响应对 service.test.local
的请求。
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 service_private_key = rsa.generate_private_key( public_exponent =65537, key_size =2048, backend =default_backend() ) service_public_key = service_private_key.public_key() builder = x509.CertificateBuilder() builder = builder.subject_name(x509.Name([ x509.NameAttribute(NameOID.COMMON_NAME, 'service.test.local' ) ])) builder = builder.not_valid_before(yesterday) builder = builder.not_valid_after(tomorrow) builder = builder.public_key(public_key) certificate = builder.sign( private_key =private_key, algorithm =hashes.SHA256(), backend =default_backend() ) private_bytes = service_private_key.private_bytes( encoding =serialization.Encoding.PEM, format =serialization.PrivateFormat.TraditionalOpenSSL, encryption_algorithm =serialization.NoEncrption()) public_bytes = certificate.public_bytes( encoding =serialization.Encoding.PEM) with open("service.pem" , "wb" ) as fout: fout.write(private_bytes + public_bytes)
现在 service.pem
文件有一个私钥和一个“有效”的证书:它已由本地的 CA 签名。该文件的格式可以给 Nginx、HAProxy 或大多数其他 HTTPS 服务器使用。
通过将此逻辑用在测试脚本中,只要客户端配置信任该 CA,那么就可以轻松创建看起来真实的 HTTPS 服务器。
via: https://opensource.com/article/19/4/certificate-authority
作者:Moshe Zadka 选题:lujun9972 译者:geekpi 校对:wxy
本文由 LCTT 原创编译,Linux中国 荣誉推出