Setup SSL using .PFX file on nginx/apache2

lightsong發表於2024-06-25

Setup SSL using .PFX file on nginx/apache2

https://xy2z.io/posts/2020-pfx-certificates-nginx-apache2/

A complete guide to using a PFX certificate on your websites

Intro

A pfx file is password protected certificate archive which contains your certificate and the private key.

Certificate extensions can be confusing since there's so many different ones (.crt, .cert, .key, .pem, .csr, etc.). Personally I use the same extensions (.crt and .key) as nginx https documentation.

  • domain.tld.key The private decrypted RSA key file for the certificate. (ssl_certificate_key)
  • domain.tld.crt The certificate file for the domain (without)
  • bundle.crt The certificate file for the issuer
  • domain.tld.chained.crt The concatted file which consists of domain.tld.crt and bundle.crt (ssl_certificate)

Get the .key file

Extract the encrypted key using:

openssl pkcs12 -in certfile.pfx -nocerts -out domain.tld.encrypted.key

Decrypt the encrypted key using:

openssl rsa -in domain.tld.encrypted.key -out domain.tld.key

Delete the domain.tld.encrypted.key file since we won't need it.

Get the .crt file

Get your domain certificate using:

openssl pkcs12 -in certfile.pfx -clcerts -nokeys -out domain.tld.crt

Get your CA certificate using:

openssl pkcs12 -in certfile.pfx -cacerts -out bundle.crt

Concat the 2 .crt files into a chained.crt:

cat domain.tld.crt bundle.crt > domain.tld.chained.crt

Delete the bundle.crt and domain.tld.crt files.

Move the certificate

Move the files to the server in the dir /etc/ssl/private/ and make sure to secure the files by setting these permissions:

sudo chmod 600 domain.tld.*
sudo chown root:root domain.tld.*

Webserver conf

Update your webserver configuration for your site and add these to the sites you want HTTPS on.

# nginx
ssl on;
ssl_certificate     /etc/ssl/private/domain.tld.chained.crt;
ssl_certificate_key /etc/ssl/private/domain.tld.key;

# apache2 conf
SSLEngine on
SSLCertificateFile      /etc/ssl/private/domain.tld.chained.crt
SSLCertificateKeyFile   /etc/ssl/private/domain.tld.key

Remember to reload the service, or restart if it's a new site.

others

https://www.koskila.net/how-to-export-a-certificate-and-a-private-key-from-a-pfx-using-openssl/

https://www.entrust.com/knowledgebase/ssl/how-do-i-convert-a-pfx-to-be-used-with-an-apache-server#:~:text=Using%20Open%20SSL%2C%20you%20can%20extract%20the%20certificate,key%20that%20you%20have%20extract%20will%20be%20encrypted.

yiyan

https://yiyan.baidu.com/

PFX字尾的檔案是一種基於PKCS#12標準的檔案格式,主要用於儲存和傳輸數字證書和私鑰。以下是關於PFX檔案的具體資訊:

  1. 檔案格式:PFX檔案是二進位制格式,通常以.pfx或.p12副檔名儲存。
  2. 內容組成:PFX檔案通常包含證書、私鑰和可選的密碼,用於保護這些敏感資訊。這些證書和私鑰可以用於確定使用者或裝置的身份,以訪問某些檔案、系統或網路。
  3. 用途:PFX檔案通常用於將證書和私鑰打包到一個檔案中,以便於匯入到應用程式或作業系統的金鑰庫中。例如,在Web伺服器上配置SSL證書時,常常需要用到PFX檔案。
  4. 安全性:PFX檔案需要密碼才能使用,這有助於保護使用者免受駭客、第三方使用者或惡意應用程式的侵害,防止他們未經授權地訪問系統和網路資源。
  5. 開啟方式:PFX檔案可以使用支援該格式的應用程式開啟,如Adobe Acrobat X或Adobe Reader(在Mac和Microsoft Windows系統中)。

總的來說,PFX檔案是一種安全的檔案格式,用於儲存和傳輸數字證書和私鑰,以便在加密通訊和身份驗證過程中使用。

PFX檔案的全稱是Personal Information Exchange,它基於PKCS#12(Public-Key Cryptography Standards #12)標準,是一種二進位制格式的檔案,用於儲存私鑰證書以及可能還有對應的公鑰證書鏈,通常還包括用於加密私鑰的可選密碼。PFX檔案常常在SSL配置或郵件客戶端證書安裝等場景中使用。

在匯入PFX檔案時,通常需要提供一個密碼來解密檔案內容,以便訪問其中的私鑰和其他敏感資訊。因此,確保PFX檔案及其密碼的安全是非常重要的。

在Python中,處理PFX(或P12)檔案以提取證書和私鑰通常需要使用cryptography庫或OpenSSL命令列工具與Python的subprocess庫結合使用。

cryptography庫本身並不直接支援從PFX檔案中提取證書和私鑰,但它可以處理提取出來的證書和私鑰格式(如PEM或DER)。不過,你可以使用OpenSSL命令列工具來轉換PFX檔案,並透過Python的subprocess庫來呼叫這些命令。

以下是一個使用subprocess和OpenSSL命令列工具從PFX檔案中提取證書和私鑰的示例:

python

import subprocess
import os

def extract_certs_from_pfx(pfx_file, password, cert_output_file, key_output_file):
# OpenSSL命令列來提取證書
cmd_extract_cert = [
'openssl', 'pkcs12', '-in', pfx_file,
'-clcerts', '-nokeys', '-out', cert_output_file,
'-passin', 'pass:{}'.format(password)
]
subprocess.run(cmd_extract_cert, check=True)

# OpenSSL命令列來提取私鑰
cmd_extract_key = [
'openssl', 'pkcs12', '-in', pfx_file,
'-nocerts', '-nodes', '-out', key_output_file,
'-passin', 'pass:{}'.format(password)
]
subprocess.run(cmd_extract_key, check=True)

# 示例使用
pfx_file = 'path_to_your_pfx_file.pfx'
password = 'your_pfx_password'
cert_output_file = 'extracted_certificate.pem'
key_output_file = 'extracted_private_key.pem'


extract_certs_from_pfx(pfx_file, password, cert_output_file, key_output_file)

請注意,這個示例假設openssl命令已經安裝在你的系統上,並且可以在你的Python指令碼的執行環境中訪問。此外,出於安全考慮,不要直接在程式碼中硬編碼密碼,而是考慮使用環境變數或安全的方式來處理密碼。

另外,如果你正在尋找一個純Python的解決方案,並且不想依賴外部工具,你可能需要查詢或編寫一個能夠解析PFX檔案格式的庫,但這通常比使用現有的命令列工具要複雜得多。

在Python中直接操作PFX檔案(也稱為P12檔案)以提取證書和私鑰並不簡單,因為Python的標準庫中沒有直接處理這種格式的工具。然而,你可以使用cryptography庫(配合pyOpenSSL或oscrypto)或者透過呼叫OpenSSL命令列工具來完成這個任務。
使用subprocess呼叫OpenSSL命令列工具

這是一個簡單的方法,假設你的系統上已經安裝了OpenSSL。

python

import subprocess

def extract_from_pfx(pfx_path, password, cert_path, key_path):
# 提取證書
cert_cmd = [
'openssl', 'pkcs12', '-in', pfx_path,
'-clcerts', '-nokeys', '-out', cert_path,
'-passin', 'pass:{}'.format(password)
]
subprocess.run(cert_cmd, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

# 提取私鑰(注意:這將私鑰儲存為未加密的PEM格式)
key_cmd = [
'openssl', 'pkcs12', '-in', pfx_path,
'-nocerts', '-nodes', '-out', key_path,
'-passin', 'pass:{}'.format(password)
]
subprocess.run(key_cmd, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

# 示例使用
pfx_path = 'path_to_your_pfx_file.pfx'
password = 'your_pfx_password'
cert_path = 'extracted_certificate.pem'
key_path = 'extracted_private_key.pem'


extract_from_pfx(pfx_path, password, cert_path, key_path)

使用pyOpenSSL庫

pyOpenSSL是一個Python的OpenSSL封裝,允許你在Python中使用許多OpenSSL的功能。

首先,你需要安裝pyOpenSSL和cryptography庫(如果尚未安裝):

bash

pip install pyopenssl cryptography

然後,你可以使用以下程式碼來提取證書和私鑰:

python

from OpenSSL import crypto

def extract_from_pfx_pyopenssl(pfx_path, password, cert_path, key_path):
with open(pfx_path, 'rb') as pfx_file:
pfx_data = pfx_file.read()
p12 = crypto.load_pkcs12(pfx_data, password.encode())

# 提取證書並儲存為PEM格式
with open(cert_path, 'wb') as cert_file:
cert_file.write(crypto.dump_certificate(crypto.FILETYPE_PEM, p12.get_certificate()))

# 提取私鑰並儲存為PEM格式(注意:這將私鑰儲存為未加密的PEM格式)
with open(key_path, 'wb') as key_file:
key_file.write(crypto.dump_privatekey(crypto.FILETYPE_PEM, p12.get_privatekey()))

# 示例使用
pfx_path = 'path_to_your_pfx_file.pfx'
password = 'your_pfx_password'
cert_path = 'extracted_certificate.pem'
key_path = 'extracted_private_key.pem'


extract_from_pfx_pyopenssl(pfx_path, password, cert_path, key_path)

請注意,使用pyOpenSSL或OpenSSL命令列工具時,提取的私鑰預設是不加密的。如果你需要加密的私鑰,你可能需要額外的步驟來加密它。同時,請確保不要在生產環境中硬編碼密碼,而是使用環境變數或安全的密碼管理方式。

相關文章