mirror of
https://github.com/yt-dlp/yt-dlp.git
synced 2024-11-27 10:31:29 +00:00
[aes] Add unpad_pkcs7
This commit is contained in:
parent
c533c89ce1
commit
1d3586d0d5
|
@ -2,8 +2,15 @@
|
||||||
|
|
||||||
from math import ceil
|
from math import ceil
|
||||||
|
|
||||||
from .compat import compat_b64decode, compat_pycrypto_AES
|
from .compat import (
|
||||||
from .utils import bytes_to_intlist, intlist_to_bytes
|
compat_b64decode,
|
||||||
|
compat_ord,
|
||||||
|
compat_pycrypto_AES,
|
||||||
|
)
|
||||||
|
from .utils import (
|
||||||
|
bytes_to_intlist,
|
||||||
|
intlist_to_bytes,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
if compat_pycrypto_AES:
|
if compat_pycrypto_AES:
|
||||||
|
@ -25,6 +32,10 @@ def aes_gcm_decrypt_and_verify_bytes(data, key, tag, nonce):
|
||||||
return intlist_to_bytes(aes_gcm_decrypt_and_verify(*map(bytes_to_intlist, (data, key, tag, nonce))))
|
return intlist_to_bytes(aes_gcm_decrypt_and_verify(*map(bytes_to_intlist, (data, key, tag, nonce))))
|
||||||
|
|
||||||
|
|
||||||
|
def unpad_pkcs7(data):
|
||||||
|
return data[:-compat_ord(data[-1])]
|
||||||
|
|
||||||
|
|
||||||
BLOCK_SIZE_BYTES = 16
|
BLOCK_SIZE_BYTES = 16
|
||||||
|
|
||||||
|
|
||||||
|
@ -506,5 +517,6 @@ def ghash(subkey, data):
|
||||||
'aes_encrypt',
|
'aes_encrypt',
|
||||||
'aes_gcm_decrypt_and_verify',
|
'aes_gcm_decrypt_and_verify',
|
||||||
'aes_gcm_decrypt_and_verify_bytes',
|
'aes_gcm_decrypt_and_verify_bytes',
|
||||||
'key_expansion'
|
'key_expansion',
|
||||||
|
'unpad_pkcs7',
|
||||||
]
|
]
|
||||||
|
|
|
@ -11,7 +11,11 @@
|
||||||
from enum import Enum, auto
|
from enum import Enum, auto
|
||||||
from hashlib import pbkdf2_hmac
|
from hashlib import pbkdf2_hmac
|
||||||
|
|
||||||
from .aes import aes_cbc_decrypt_bytes, aes_gcm_decrypt_and_verify_bytes
|
from .aes import (
|
||||||
|
aes_cbc_decrypt_bytes,
|
||||||
|
aes_gcm_decrypt_and_verify_bytes,
|
||||||
|
unpad_pkcs7,
|
||||||
|
)
|
||||||
from .compat import (
|
from .compat import (
|
||||||
compat_b64decode,
|
compat_b64decode,
|
||||||
compat_cookiejar_Cookie,
|
compat_cookiejar_Cookie,
|
||||||
|
@ -846,10 +850,9 @@ def pbkdf2_sha1(password, salt, iterations, key_length):
|
||||||
|
|
||||||
|
|
||||||
def _decrypt_aes_cbc(ciphertext, key, logger, initialization_vector=b' ' * 16):
|
def _decrypt_aes_cbc(ciphertext, key, logger, initialization_vector=b' ' * 16):
|
||||||
plaintext = aes_cbc_decrypt_bytes(ciphertext, key, initialization_vector)
|
plaintext = unpad_pkcs7(aes_cbc_decrypt_bytes(ciphertext, key, initialization_vector))
|
||||||
padding_length = plaintext[-1]
|
|
||||||
try:
|
try:
|
||||||
return plaintext[:-padding_length].decode('utf-8')
|
return plaintext.decode('utf-8')
|
||||||
except UnicodeDecodeError:
|
except UnicodeDecodeError:
|
||||||
logger.warning('failed to decrypt cookie (AES-CBC) because UTF-8 decoding failed. Possibly the key is wrong?', only_once=True)
|
logger.warning('failed to decrypt cookie (AES-CBC) because UTF-8 decoding failed. Possibly the key is wrong?', only_once=True)
|
||||||
return None
|
return None
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
from .common import FileDownloader
|
from .common import FileDownloader
|
||||||
from .http import HttpFD
|
from .http import HttpFD
|
||||||
from ..aes import aes_cbc_decrypt_bytes
|
from ..aes import aes_cbc_decrypt_bytes, unpad_pkcs7
|
||||||
from ..compat import (
|
from ..compat import (
|
||||||
compat_os_name,
|
compat_os_name,
|
||||||
compat_urllib_error,
|
compat_urllib_error,
|
||||||
|
@ -366,8 +366,7 @@ def decrypt_fragment(fragment, frag_content):
|
||||||
# not what it decrypts to.
|
# not what it decrypts to.
|
||||||
if self.params.get('test', False):
|
if self.params.get('test', False):
|
||||||
return frag_content
|
return frag_content
|
||||||
decrypted_data = aes_cbc_decrypt_bytes(frag_content, decrypt_info['KEY'], iv)
|
return unpad_pkcs7(aes_cbc_decrypt_bytes(frag_content, decrypt_info['KEY'], iv))
|
||||||
return decrypted_data[:-decrypted_data[-1]]
|
|
||||||
|
|
||||||
return decrypt_fragment
|
return decrypt_fragment
|
||||||
|
|
||||||
|
|
|
@ -8,11 +8,10 @@
|
||||||
import random
|
import random
|
||||||
|
|
||||||
from .common import InfoExtractor
|
from .common import InfoExtractor
|
||||||
from ..aes import aes_cbc_decrypt
|
from ..aes import aes_cbc_decrypt_bytes, unpad_pkcs7
|
||||||
from ..compat import (
|
from ..compat import (
|
||||||
compat_HTTPError,
|
compat_HTTPError,
|
||||||
compat_b64decode,
|
compat_b64decode,
|
||||||
compat_ord,
|
|
||||||
)
|
)
|
||||||
from ..utils import (
|
from ..utils import (
|
||||||
ass_subtitles_timecode,
|
ass_subtitles_timecode,
|
||||||
|
@ -84,14 +83,11 @@ def _get_subtitles(self, sub_url, video_id):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# http://animedigitalnetwork.fr/components/com_vodvideo/videojs/adn-vjs.min.js
|
# http://animedigitalnetwork.fr/components/com_vodvideo/videojs/adn-vjs.min.js
|
||||||
dec_subtitles = intlist_to_bytes(aes_cbc_decrypt(
|
dec_subtitles = unpad_pkcs7(aes_cbc_decrypt_bytes(
|
||||||
bytes_to_intlist(compat_b64decode(enc_subtitles[24:])),
|
compat_b64decode(enc_subtitles[24:]),
|
||||||
bytes_to_intlist(binascii.unhexlify(self._K + 'ab9f52f5baae7c72')),
|
binascii.unhexlify(self._K + 'ab9f52f5baae7c72'),
|
||||||
bytes_to_intlist(compat_b64decode(enc_subtitles[:24]))
|
compat_b64decode(enc_subtitles[:24])))
|
||||||
))
|
subtitles_json = self._parse_json(dec_subtitles.decode(), None, fatal=False)
|
||||||
subtitles_json = self._parse_json(
|
|
||||||
dec_subtitles[:-compat_ord(dec_subtitles[-1])].decode(),
|
|
||||||
None, fatal=False)
|
|
||||||
if not subtitles_json:
|
if not subtitles_json:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
|
@ -7,13 +7,11 @@
|
||||||
|
|
||||||
|
|
||||||
from .common import InfoExtractor
|
from .common import InfoExtractor
|
||||||
from ..aes import aes_cbc_decrypt
|
from ..aes import aes_cbc_decrypt_bytes, unpad_pkcs7
|
||||||
from ..compat import compat_urllib_parse_unquote
|
from ..compat import compat_urllib_parse_unquote
|
||||||
from ..utils import (
|
from ..utils import (
|
||||||
bytes_to_intlist,
|
|
||||||
ExtractorError,
|
ExtractorError,
|
||||||
int_or_none,
|
int_or_none,
|
||||||
intlist_to_bytes,
|
|
||||||
float_or_none,
|
float_or_none,
|
||||||
mimetype2ext,
|
mimetype2ext,
|
||||||
str_or_none,
|
str_or_none,
|
||||||
|
@ -191,13 +189,11 @@ def hex_to_bytes(hex):
|
||||||
def decrypt_uri(e):
|
def decrypt_uri(e):
|
||||||
n = int(e[2:10], 16)
|
n = int(e[2:10], 16)
|
||||||
a = e[10 + n:]
|
a = e[10 + n:]
|
||||||
data = bytes_to_intlist(hex_to_bytes(e[10:10 + n]))
|
data = hex_to_bytes(e[10:10 + n])
|
||||||
key = bytes_to_intlist(hashlib.sha256(
|
key = hashlib.sha256(('%s:sRBzYNXBzkKgnjj8pGtkACch' % a).encode('utf-8')).digest()
|
||||||
('%s:sRBzYNXBzkKgnjj8pGtkACch' % a).encode('utf-8')).digest())
|
iv = hex_to_bytes(a)
|
||||||
iv = bytes_to_intlist(hex_to_bytes(a))
|
decrypted = unpad_pkcs7(aes_cbc_decrypt_bytes(data, key, iv))
|
||||||
decrypted = aes_cbc_decrypt(data, key, iv)
|
return decrypted.decode('utf-8').split('?')[0]
|
||||||
return intlist_to_bytes(
|
|
||||||
decrypted[:-decrypted[-1]]).decode('utf-8').split('?')[0]
|
|
||||||
|
|
||||||
for asset in assets:
|
for asset in assets:
|
||||||
kind = asset.get('Kind')
|
kind = asset.get('Kind')
|
||||||
|
|
|
@ -5,11 +5,9 @@
|
||||||
import hashlib
|
import hashlib
|
||||||
|
|
||||||
from .common import InfoExtractor
|
from .common import InfoExtractor
|
||||||
from ..aes import aes_cbc_decrypt
|
from ..aes import aes_cbc_decrypt_bytes, unpad_pkcs7
|
||||||
from ..utils import (
|
from ..utils import (
|
||||||
bytes_to_intlist,
|
|
||||||
int_or_none,
|
int_or_none,
|
||||||
intlist_to_bytes,
|
|
||||||
parse_codecs,
|
parse_codecs,
|
||||||
parse_duration,
|
parse_duration,
|
||||||
)
|
)
|
||||||
|
@ -47,10 +45,8 @@ def _real_extract(self, url):
|
||||||
}))
|
}))
|
||||||
key = hashlib.pbkdf2_hmac(
|
key = hashlib.pbkdf2_hmac(
|
||||||
'sha1', video_guid.replace('-', '').encode(), enc_data[:16], 1)[:16]
|
'sha1', video_guid.replace('-', '').encode(), enc_data[:16], 1)[:16]
|
||||||
dec_data = aes_cbc_decrypt(
|
dec_data = unpad_pkcs7(aes_cbc_decrypt_bytes(enc_data[32:], key, enc_data[16:32]))
|
||||||
bytes_to_intlist(enc_data[32:]), bytes_to_intlist(key),
|
sources = self._parse_json(dec_data, video_guid)
|
||||||
bytes_to_intlist(enc_data[16:32]))
|
|
||||||
sources = self._parse_json(intlist_to_bytes(dec_data[:-dec_data[-1]]), video_guid)
|
|
||||||
|
|
||||||
formats = []
|
formats = []
|
||||||
for source in sources:
|
for source in sources:
|
||||||
|
|
|
@ -4,16 +4,13 @@
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from .common import InfoExtractor
|
from .common import InfoExtractor
|
||||||
from ..aes import aes_cbc_decrypt
|
from ..aes import aes_cbc_decrypt_bytes, unpad_pkcs7
|
||||||
from ..compat import (
|
from ..compat import (
|
||||||
compat_b64decode,
|
compat_b64decode,
|
||||||
compat_ord,
|
|
||||||
compat_str,
|
compat_str,
|
||||||
)
|
)
|
||||||
from ..utils import (
|
from ..utils import (
|
||||||
bytes_to_intlist,
|
|
||||||
ExtractorError,
|
ExtractorError,
|
||||||
intlist_to_bytes,
|
|
||||||
int_or_none,
|
int_or_none,
|
||||||
strip_or_none,
|
strip_or_none,
|
||||||
)
|
)
|
||||||
|
@ -142,17 +139,12 @@ def _real_extract(self, url):
|
||||||
self._BACKWERK_BASE_URL + 'stream/video/' + video_id, video_id)
|
self._BACKWERK_BASE_URL + 'stream/video/' + video_id, video_id)
|
||||||
|
|
||||||
data, iv = compat_b64decode(stream_data['streamUrl']).decode().split(':')
|
data, iv = compat_b64decode(stream_data['streamUrl']).decode().split(':')
|
||||||
stream_url = intlist_to_bytes(aes_cbc_decrypt(
|
stream_url = unpad_pkcs7(aes_cbc_decrypt_bytes(
|
||||||
bytes_to_intlist(compat_b64decode(data)),
|
compat_b64decode(data), self._AES_KEY, compat_b64decode(iv)))
|
||||||
bytes_to_intlist(self._AES_KEY),
|
|
||||||
bytes_to_intlist(compat_b64decode(iv))
|
|
||||||
))
|
|
||||||
if b'rtl2_you_video_not_found' in stream_url:
|
if b'rtl2_you_video_not_found' in stream_url:
|
||||||
raise ExtractorError('video not found', expected=True)
|
raise ExtractorError('video not found', expected=True)
|
||||||
|
|
||||||
formats = self._extract_m3u8_formats(
|
formats = self._extract_m3u8_formats(stream_url.decode(), video_id, 'mp4', 'm3u8_native')
|
||||||
stream_url[:-compat_ord(stream_url[-1])].decode(),
|
|
||||||
video_id, 'mp4', 'm3u8_native')
|
|
||||||
self._sort_formats(formats)
|
self._sort_formats(formats)
|
||||||
|
|
||||||
video_data = self._download_json(
|
video_data = self._download_json(
|
||||||
|
|
|
@ -2,10 +2,9 @@
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from .common import InfoExtractor
|
from .common import InfoExtractor
|
||||||
from ..aes import aes_cbc_decrypt
|
from ..aes import aes_cbc_decrypt, unpad_pkcs7
|
||||||
from ..compat import (
|
from ..compat import (
|
||||||
compat_b64decode,
|
compat_b64decode,
|
||||||
compat_ord,
|
|
||||||
)
|
)
|
||||||
from ..utils import (
|
from ..utils import (
|
||||||
bytes_to_intlist,
|
bytes_to_intlist,
|
||||||
|
@ -76,8 +75,7 @@ def _real_extract(self, url):
|
||||||
url_data = bytes_to_intlist(compat_b64decode(data_json['new_play_url']))
|
url_data = bytes_to_intlist(compat_b64decode(data_json['new_play_url']))
|
||||||
key = bytes_to_intlist(compat_b64decode(data_json['key']))
|
key = bytes_to_intlist(compat_b64decode(data_json['key']))
|
||||||
iv = [0] * 16
|
iv = [0] * 16
|
||||||
m3u8_url = intlist_to_bytes(aes_cbc_decrypt(url_data, key, iv))
|
m3u8_url = unpad_pkcs7(intlist_to_bytes(aes_cbc_decrypt(url_data, key, iv))).decode('ascii')
|
||||||
m3u8_url = m3u8_url[:-compat_ord((m3u8_url[-1]))].decode('ascii')
|
|
||||||
formats, m3u8_subs = self._extract_m3u8_formats_and_subtitles(m3u8_url, video_id, fatal=False, headers={'stream_key': data_json['stream_key']})
|
formats, m3u8_subs = self._extract_m3u8_formats_and_subtitles(m3u8_url, video_id, fatal=False, headers={'stream_key': data_json['stream_key']})
|
||||||
self._sort_formats(formats)
|
self._sort_formats(formats)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue