z230
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
"""
|
||||
Přihlášení na portál RBP pomocí certifikátu (bez NMSigneru).
|
||||
|
||||
JAK TO FUNGUJE:
|
||||
Portál používá challenge-response autentizaci (stejná platforma jako VoZP):
|
||||
1. Skript načte přihlašovací stránku → dostane session cookie (PHPSESSID)
|
||||
2. Požádá server o zprávu k podpisu (challenge s časovým razítkem)
|
||||
3. Podepíše ji certifikátem jako PKCS7/CMS detached signature (RSA + SHA-256)
|
||||
4. Odešle podpis na server → server ověří a vrátí přihlášení
|
||||
5. Výsledné cookies uloží do rbp_cookies.json pro další skripty
|
||||
|
||||
POUŽITÍ:
|
||||
pip install requests cryptography
|
||||
python 01_prihlaseni.py
|
||||
|
||||
CERTIFIKÁT:
|
||||
Exportuj z Windows: certmgr.msc → Osobní → pravý klik → Exportovat
|
||||
Formát: PKCS #12 (.PFX), bez CA řetězu
|
||||
Uložit do: ../../Certificates/MBQualifiedCert.pfx
|
||||
"""
|
||||
|
||||
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__), "rbp_cookies.json"))
|
||||
|
||||
BASE_URL = "https://portal.rbp-zp.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.rbp-zp.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()
|
||||
Reference in New Issue
Block a user