Add pfx_extract.py

This commit is contained in:
gru
2025-11-26 08:29:12 +01:00
commit 1971b210d6

119
pfx_extract.py Normal file
View File

@@ -0,0 +1,119 @@
#!/usr/bin/env python3
import argparse
import os
import subprocess
import tarfile
import tempfile
import shutil
import sys
def run_cmd(cmd, password):
env = os.environ.copy()
# hasło przekazujemy przez zmienną środowiskową, żeby nie wisiało w ps
env["PFXPASSWORD"] = password
# używamy -passin env:PFXPASSWORD w openssl
result = subprocess.run(
cmd,
env=env,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
)
if result.returncode != 0:
print("Błąd wykonania:", " ".join(cmd), file=sys.stderr)
print(result.stderr, file=sys.stderr)
sys.exit(result.returncode)
return result.stdout
def extract_from_pfx(pfx_path, password, out_dir, base_name):
key_path = os.path.join(out_dir, f"{base_name}.key.pem")
cert_path = os.path.join(out_dir, f"{base_name}.cert.pem")
chain_path = os.path.join(out_dir, f"{base_name}.chain.pem")
# klucz prywatny
run_cmd([
"openssl", "pkcs12",
"-in", pfx_path,
"-passin", "env:PFXPASSWORD",
"-nodes",
"-nocerts",
"-out", key_path
], password)
# cert końcowy
run_cmd([
"openssl", "pkcs12",
"-in", pfx_path,
"-passin", "env:PFXPASSWORD",
"-clcerts",
"-nokeys",
"-out", cert_path
], password)
# certy pośrednie (CA chain) może być puste, wtedy plik zostanie, ale bez zawartości
run_cmd([
"openssl", "pkcs12",
"-in", pfx_path,
"-passin", "env:PFXPASSWORD",
"-nokeys",
"-cacerts",
"-out", chain_path
], password)
return key_path, cert_path, chain_path
def create_tar_gz(archive_name, files):
with tarfile.open(archive_name, "w:gz") as tar:
for f in files:
if os.path.isfile(f):
tar.add(f, arcname=os.path.basename(f))
def main():
parser = argparse.ArgumentParser(
description="Rozszyfruj PFX i spakuj key/cert/chain do tar.gz"
)
parser.add_argument("pfx", help="Ścieżka do pliku .pfx/.p12")
parser.add_argument("password", help="Hasło do pliku PFX")
parser.add_argument(
"-o", "--output-dir",
default=".",
help="Katalog wyjściowy (domyślnie bieżący)"
)
args = parser.parse_args()
pfx_path = os.path.abspath(args.pfx)
if not os.path.isfile(pfx_path):
print(f"Nie znaleziono pliku: {pfx_path}", file=sys.stderr)
sys.exit(1)
os.makedirs(args.output_dir, exist_ok=True)
base_name = os.path.splitext(os.path.basename(pfx_path))[0]
archive_name = os.path.join(args.output_dir, f"{base_name}.tar.gz")
# pracujemy w katalogu tymczasowym, potem wyniki kopiujemy
tmpdir = tempfile.mkdtemp(prefix="pfx_extract_")
try:
key_path, cert_path, chain_path = extract_from_pfx(
pfx_path, args.password, tmpdir, base_name
)
# kopiujemy pliki PEM do katalogu wyjściowego (opcjonalne, ale zwykle przydatne)
final_key = shutil.copy(key_path, os.path.join(args.output_dir, os.path.basename(key_path)))
final_cert = shutil.copy(cert_path, os.path.join(args.output_dir, os.path.basename(cert_path)))
final_chain = shutil.copy(chain_path, os.path.join(args.output_dir, os.path.basename(chain_path)))
# tworzymy tar.gz z tych 3 plików
create_tar_gz(archive_name, [final_key, final_cert, final_chain])
print("Utworzono pliki:")
print(" Klucz: ", final_key)
print(" Certyfikat: ", final_cert)
print(" Chain: ", final_chain)
print("Archiwum tar.gz:", archive_name)
finally:
shutil.rmtree(tmpdir, ignore_errors=True)
if __name__ == "__main__":
main()