Linux中國

自己成為一個證書頒發機構(CA)

傳輸層安全(TLS)模型(有時也稱它的舊名稱 SSL)基於 證書頒發機構 certificate authoritie CA)的概念。這些機構受到瀏覽器和操作系統的信任,從而簽名伺服器的的證書以用於驗證其所有權。

但是,對於內部網路,微服務架構或集成測試,有時候本地 CA更有用:一個只在內部受信任的 CA,然後簽名本地伺服器的證書

這對集成測試特別有意義。獲取證書可能會帶來負擔,因為這會佔用伺服器幾分鐘。但是在代碼中使用「忽略證書」可能會被引入到生產環境,從而導致安全災難。

CA 證書與常規伺服器證書沒有太大區別。重要的是它被本地代碼信任。例如,在 Python requests 庫中,可以通過將 REQUESTS_CA_BUNDLE 變數設置為包含此證書的目錄來完成。

在為集成測試創建證書的例子中,不需要長期的證書:如果你的集成測試需要超過一天,那麼你應該已經測試失敗了。

因此,計算昨天明天作為有效期間隔:

>>> import datetime
>>> one_day = datetime.timedelta(days=1)
>>> today = datetime.date.today()
>>> yesterday = today - one_day
>>> tomorrow = today - one_day

現在你已準備好創建一個簡單的 CA 證書。你需要生成私鑰,創建公鑰,設置 CA 的「參數」,然後自簽名證書:CA 證書總是自簽名的。最後,導出證書文件以及私鑰文件。

from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives import hashes, serialization
from cryptography import x509
from 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 的請求。

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中國 榮譽推出


本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive

對這篇文章感覺如何?

太棒了
0
不錯
0
愛死了
0
不太好
0
感覺很糟
0
雨落清風。心向陽

    You may also like

    Leave a reply

    您的電子郵箱地址不會被公開。 必填項已用 * 標註

    此站點使用Akismet來減少垃圾評論。了解我們如何處理您的評論數據

    More in:Linux中國