#!/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()