Files
ordinaceprojekt/Insurance/StahováníZpráv/209 ZPŠ/01_prihlaseni.py
T
2026-04-20 15:41:13 +02:00

91 lines
3.0 KiB
Python

"""
Přihlášení na portál ZPŠ pomocí certifikátu (bez NMSigneru).
Stejná platforma jako VoZP a RBP (portalzp.cz).
POUŽITÍ:
pip install requests cryptography
python 01_prihlaseni.py
"""
import json
import os
import requests
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.serialization import pkcs7, pkcs12
PFX_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), "../../Certificates/MBQualifiedCert.pfx"))
PFX_PASSWORD = b"Vlado7309208104++"
COOKIES_FILE = os.path.abspath(os.path.join(os.path.dirname(__file__), "zps_cookies.json"))
BASE_URL = "https://portal.zpskoda.cz"
CHALLENGE_URL = f"{BASE_URL}/json-api/prihlaseni/prihlasovaci-zprava"
CERTLOGIN_URL = f"{BASE_URL}/json-api/prihlaseni/prihlaseni-certifikatem"
def main() -> None:
session = requests.Session()
session.headers.update({
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
"X-Requested-With": "XMLHttpRequest",
"Origin": BASE_URL,
"Referer": BASE_URL + "/",
})
# 1. Načti login stránku → session cookie
r = session.get(f"{BASE_URL}/app/prihlaseni")
r.raise_for_status()
session.cookies.set("pzp_sign", "CERT", domain="portal.zpskoda.cz", path="/")
# 2. Získej challenge
r = session.post(CHALLENGE_URL, json={"login_sign": "CERT"},
headers={"Content-Type": "application/json; charset=UTF-8"})
r.raise_for_status()
zprava = r.json()["data"]["zprava"]
# 3. Podepis (PKCS7 detached, RSA + SHA-256, bez CA řetězu)
with open(PFX_PATH, "rb") as f:
private_key, cert, _ = pkcs12.load_key_and_certificates(f.read(), PFX_PASSWORD)
podpis = (
pkcs7.PKCS7SignatureBuilder()
.set_data(zprava.encode("utf-8"))
.add_signer(cert, private_key, hashes.SHA256())
.sign(serialization.Encoding.PEM, [pkcs7.PKCS7Options.DetachedSignature])
.decode("ascii").strip()
)
# 4. Přihlas se
r = session.post(CERTLOGIN_URL, json={"zprava": zprava, "podpis": podpis},
headers={"Content-Type": "application/json; charset=UTF-8"})
r.raise_for_status()
data = r.json()["data"]
if not data.get("prihlasen"):
print(f"Prihlaseni selhalo: {r.json().get('errMsg', '')}")
return
print(f"Prihlaseni uspesne - {data.get('url', '')}")
# 5. Ulož cookies
cookies = [
{
"name": c.name,
"value": c.value,
"domain": c.domain if c.domain.startswith(".") else "." + c.domain,
"path": c.path or "/",
"expires": int(c.expires) if c.expires else -1,
"secure": bool(c.secure),
"httpOnly": False,
"sameSite": "Lax",
}
for c in session.cookies
]
with open(COOKIES_FILE, "w", encoding="utf-8") as f:
json.dump(cookies, f, indent=2, ensure_ascii=False)
print(f"Ulozeno {len(cookies)} cookies -> {COOKIES_FILE}")
if __name__ == "__main__":
main()