From b5f957b957acb1ebc2d77827bdc7dfcdb785208e Mon Sep 17 00:00:00 2001 From: CDM-Project Date: Mon, 16 Sep 2024 22:27:07 -0400 Subject: [PATCH] Update Decrypt.py - Added widevine challenge / response crawler. --- CDRM_Modules/Decrypt.py | 89 +++++++++++++++++++++++++++++++++-------- 1 file changed, 73 insertions(+), 16 deletions(-) diff --git a/CDRM_Modules/Decrypt.py b/CDRM_Modules/Decrypt.py index 8c0abe9..8a161ae 100644 --- a/CDRM_Modules/Decrypt.py +++ b/CDRM_Modules/Decrypt.py @@ -1,3 +1,5 @@ +import base64 + import httpx from pywidevine.cdm import Cdm from pywidevine.device import Device @@ -17,6 +19,7 @@ def load_license_curl(): def __init__(self): self.headers = headers self.cookies = cookies + self.data = data try: with open(f'{os.getcwd()}/License_cURL.py', 'r') as file: @@ -33,6 +36,10 @@ def load_license_curl(): cookies = local_namespace['cookies'] else: cookies = None + if 'data' in local_namespace: + data = local_namespace['data'] + else: + data = None return LicenseCURL() def check_if_url(string): @@ -48,6 +55,22 @@ def check_if_url(string): re.IGNORECASE) return re.match(url_pattern, string) is not None +def replace_widevine_challenge(dictionary, challenge): + for key, value in dictionary.items(): + if 'widevine' in key.lower(): + dictionary[key] = challenge + elif isinstance(value, dict): + replace_widevine_value(value, challenge_type) + + +def find_widevine_license(dictionary): + for key, value in dictionary.items(): + if 'widevine' in key.lower() or 'license' in key.lower(): + license = dictionary[key] + return license + elif isinstance(value, dict): + replace_widevine_value(value, challenge_type) + def decrypt_local_cdm(): cdm_choice = CDM_Selector.select_local_cdm() try: @@ -102,28 +125,45 @@ def decrypt_local_cdm(): headers=license_curl.headers, cookies=license_curl.cookies, data=cdm.service_certificate_challenge - ).content - cdm.set_service_certificate(session_id=session_id, certificate=service_certificate) - service_cert_set_success = True + ) + try: + cdm.set_service_certificate(session_id=session_id, certificate=service_certificate.content) + service_cert_set_success = True + except Exception as error: + try: + cdm.set_service_certificate(session_id=session_id, certificate=find_widevine_license(service_certificate.json())) + service_cert_set_success = True + except Exception as error: + print(f'{Fore.RED}An error occurred.\n\n{error}\n\nTrying without service certificate') except Exception as error: print(f'{Fore.RED}An error occurred.\n\n{error}\n\nTrying without service certificate') challenge = cdm.get_license_challenge(session_id=session_id, pssh=pssh, privacy_mode=service_cert_set_success) db_data = challenge + if license_curl.data: + try: + lic_data = replace_widevine_value(license_curl.data, base64.b64encode(challenge).decode()) + except: + pass + else: + lic_data = challenge try: license_response = httpx.post( url=user_license_url, headers=license_curl.headers, cookies=license_curl.cookies, - data=challenge - ).content + data=lic_data + ) except Exception as error: print(f'{Fore.RED}An error occurred.\n\n{error}') exit(1) try: - cdm.parse_license(session_id=session_id, license_message=license_response) + cdm.parse_license(session_id=session_id, license_message=license_response.content) except Exception as error: - print(f'{Fore.RED}An error occurred.\n\n{error}') - exit(1) + try: + cdm.parse_license(session_id=session_id, license_message=find_widevine_license(license_response.json())) + except Exception as error: + print(f'{Fore.RED}An error occurred.\n\n{error}') + exit(1) for key in cdm.get_keys(session_id): if key.type == 'CONTENT': Database.upsert_key(PSSH=f'{db_pssh}', MPD=f'{db_mpd}', KID=f'{key.kid.hex}', KEY=f'{key.key.hex()}', License_URL=f'{db_url}', Headers=f'{db_headers}', Cookies=f'{db_cookies}', Data=f'{db_data}') @@ -189,28 +229,45 @@ def decrypt_remote_cdm(): headers=license_curl.headers, cookies=license_curl.cookies, data=cdm.service_certificate_challenge - ).content - cdm.set_service_certificate(session_id=session_id, certificate=service_certificate) - service_cert_set_success = True + ) + try: + cdm.set_service_certificate(session_id=session_id, certificate=service_certificate.content) + set_service_certificate_success = True + except: + try: + cdm.set_service_certificate(session_id=session_id, certificate=find_widevine_license(service_certificate.json())) + set_service_certificate_success = True + except Exception as error: + print(f'{Fore.RED}An error occurred.\n\n{error}\n\nTrying without service certificate') except Exception as error: print(f'{Fore.RED}An error occurred.\n\n{error}\n\nTrying without service certificate') challenge = cdm.get_license_challenge(session_id=session_id, pssh=pssh, privacy_mode=service_cert_set_success) db_data = challenge + if license_curl.data: + try: + lic_data = replace_widevine_value(license_curl.data, base64.b64encode(challenge).decode()) + except: + pass + else: + lic_data = challenge try: license_response = httpx.post( url=user_license_url, headers=license_curl.headers, cookies=license_curl.cookies, - data=challenge - ).content + data=lic_data + ) except Exception as error: print(f'{Fore.RED}An error occurred.\n\n{error}') exit(1) try: - cdm.parse_license(session_id=session_id, license_message=license_response) + cdm.parse_license(session_id=session_id, license_message=license_response.content) except Exception as error: - print(f'{Fore.RED}An error occurred.\n\n{error}') - exit(1) + try: + cdm.parse_license(session_id=session_id, license_message=find_widevine_license(license_response.json())) + except Exception as error: + print(f'{Fore.RED}An error occurred.\n\n{error}') + exit(1) for key in cdm.get_keys(session_id): if key.type == 'CONTENT': Database.upsert_key(PSSH=f'{db_pssh}', MPD=f'{db_mpd}', KID=f'{key.kid.hex}', KEY=f'{key.key.hex()}', License_URL=f'{db_url}', Headers=f'{db_headers}', Cookies=f'{db_cookies}', Data=f'{db_data}')