## обзор
Эта статья предназначена только для обмена технологиями и общения и не должна использоваться в незаконных целях. Прилагается полный пример кода алгоритма восстановления подписи!
Чтобы избежать слишком большого количества кода в статье и сделать ее неудобной для чтения, все коды запросов изменены на формат запроса Curl. Пожалуйста, вставьте его самостоятельно и используйте инструмент, чтобы преобразовать его в код Python для вызова!
#### Получите разрешение на загрузку ресурсов
формат запроса Curl
curl --location 'https://creator.douyin.com/web/api/media/upload/auth/v5/' \
--header 'Cookie: {Вот файлы cookie для входа в вашу учетную запись}'
тело ответа
{
"ak": "AKLTYjdjYTUwZWQwZDU0NDRmMmEwNWU5NmE1MTdiYzUyZTg",
"auth": "{\"AccessKeyID\":\"AKTPNzAyMGQ2YTgxYj*******YjY\",\"SecretAccessKey\":\"tr3i*****4x\",\"SessionToken\":\"STS2eyJMVEFj*********WJhNiJ9\",\"ExpiredTime\":\"2024-03-20T18:18:36+08:00\",\"CurrentTime\":\"2024-03-18T18:18:36+08:00\"}",
"extra": {
"logid": "2024031818*********0",
"now": 1710757116000
},
"status_code": 0
}
// Здесь необходимо сохранить поля ak и auth. Эти два параметра будут использоваться в последующих запросах на шифрование и выделение ресурсов.
#### Получить адрес загрузки и распространения графических и текстовых ресурсов
curl --location 'https://imagex.bytedanceapi.com/?Action=ApplyImageUpload&Version=2018-08-01&ServiceId=jm8ajry58r&app_id=2906&user_id=&s=cbdzimvyprv' \
--header 'accept: */*' \
--header 'authorization: {Сгенерировано с помощью алгоритма шифрования, будет выполнен анализ и восстановление шифрования}' \
--header 'user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 Edg/122.0.0.0' \
--header 'x-amz-date: 20240318T095316Z' \
--header 'x-amz-security-token: STS2eyJMVEFj*********WJhNiJ9'
тело ответа
{
"ResponseMetadata": {
"RequestId": "202403181********FCC",
"Action": "ApplyImageUpload",
"Version": "2018-08-01",
"Service": "imagex",
"Region": "cn-north-1"
},
// Если запрос подписи успешен, будет возвращен объект Result, если он не удастся, будет возвращен объект Error;
"Result": {
// Содержимого слишком много, поэтому оно будет опущено. В основном принимает SessionKey, UploadHosts, StoreUri, Параметры аутентификации
}
}
Этот запрос в основном направлен на
headers
вauthorization
Шифрование параметров,x-amz-date
на текущий моментios8601форматировать время,x-amz-security-token
Параметры получены в запросе авторизации загрузки ресурса, полученном выше. 3. authorization Обратный анализ параметровauthorization
Параметры: AWS4-HMAC-SHA256 для шифрования. Формат: AWS4-HMAC-SHA256 Credential={параметр ak, полученный выше}/{первые 8 цифр времени в формате ios8601}/{адрес сегмента распределения ресурсов}/{имя службы распределения ресурсов}/aws4_request, SignedHeaders=x-amz-date;x-amz-security-token, Подпись={параметр шифрования}С помощью вышеуказанного формата шифрования можно проанализировать, что основными потребностями являются получение и восстановление
Адрес сегмента распределения ресурсов
,Название службы распределения ресурсов
,и последнийSignature
Создать правила。 глобальный поискAWS4-HMAC-SHA256
получатьАдрес сегмента распределения ресурсов
иНазвание службы распределения ресурсов
являются фиксированными значениями соответственноcn-north-1
иimagex
Signature
Параметры: this.signature(e, t), Продолжайте копать глубже и обнаружите, что функция a вызывается снова и снова. Функция a представляет собой стандартное шифрование AWS4-sha256.
Код восстановления процесса шифрования Python
import datetime, hashlib, hmac
from urllib.parse import urlencode
def getSignatureKey(key, date_stamp, regionName, serviceName):
kDate = hmac.new(('AWS4' + key).encode('utf-8'), date_stamp.encode("utf-8"), hashlib.sha256).digest()
kRegion = hmac.new(kDate, regionName.encode("utf-8"), hashlib.sha256).digest()
kService = hmac.new(kRegion, serviceName.encode("utf-8"), hashlib.sha256).digest()
kSigning = hmac.new(kService, 'aws4_request'.encode("utf-8"), hashlib.sha256).digest()
return kSigning
def buildStrParams(params):
url = ""
for key, value in params.items():
url += key + "=" + str(value) + "&"
return url[:-1] # Удалить последнее лишнее"&"
def random_s():
digits = '0123456789'
ascii_letters = 'abcdefghigklmnopqrstuvwxyz'
l = digits + ascii_letters
str_list = [random.choice(l) for i in range(11)]
random_str = ''.join(str_list)
return random_str
def generateAuthorization(secretAccessKey, region, service, canonical_querystring, amz_date, SessionToken, date_stamp, AccessKeyID):
signing_key = getSignatureKey(secretAccessKey, date_stamp, region, service)
canonical_headers = 'x-amz-date:' + amz_date + '\n' + 'x-amz-security-token:' + SessionToken + '\n'
canonical_request = "GET" + '\n' + "/" + '\n' + canonical_querystring + '\n' + canonical_headers + '\n' + 'x-amz-date;x-amz-security-token' + '\n' + hashlib.sha256("".encode("utf-8")).hexdigest()
algorithm = 'AWS4-HMAC-SHA256'
credential_scope = date_stamp + '/' + region + '/' + service + '/' + 'aws4_request'
string_to_sign = algorithm + '\n' + amz_date + '\n' + credential_scope + '\n' + hashlib.sha256(canonical_request.encode("utf-8")).hexdigest()
Signature = hmac.new(signing_key, string_to_sign.encode("utf-8"), hashlib.sha256).hexdigest()
data = f"AWS4-HMAC-SHA256 Credential={AccessKeyID}/{date_stamp}/{region}/{service}/aws4_request, SignedHeaders=x-amz-date;x-amz-security-token, Signature={Signature}"
return data
if __name__ == "__main__":
auth = {
"accessKeyId": "AKTPZjAzMDR******NmNlMDE",
"secretAccessKey": "AuISVb8*******PlyYEK3L2",
"sessionToken": "STS2eyJ*******ZCJ9"
}
times = datetime.datetime.utcnow()
amz_date = times.strftime('%Y%m%dT%H%M%SZ')
date_stamp = times.strftime('%Y%m%d')
region = 'cn-north-1'
service = 'imagex'
params = {
"Action": "ApplyImageUpload",
"ServiceId": "jm8ajry58r",
"Version": "2018-08-01",
"app_id": "2906",
"s": random_s,
"user_id": ""
}
canonical_querystring = buildStrParams(params)
SessionToken = auth.get('sessionToken')
AccessKeyID = auth.get('accessKeyId')
secretAccessKey = auth.get('secretAccessKey')
Authorization = generateAuthorization(secretAccessKey, region, service, canonical_querystring, amz_date, SessionToken, date_stamp, AccessKeyID)
print(Authorization)
До сих пор
Authorization
Анализ восстановления параметров завершен.Правила шифрования относительно стандартизированы.,Говорить особо нечего. После соединения заголовков и запроса заголовка мы получаем тело. ответавSessionKey
,UploadHosts
,StoreUri
,Auth
параметр,Адрес загрузки::https://{UploadHosts}/upload/v1/{storeUri}
,Адрес загрузки должен быть динамически объединен.
#### Загрузить фотографии
curl --location 'https://tos-lf-x.snssdk.com/upload/v1/*****' \
--header 'Authorization: SpaceKey/jm*******' \
--header 'Content-CRC32: ff3ceced' \
--header 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 Edg/122.0.0.0'
--data '{Содержимое файла, который вы хотите загрузить}'
в
url
для вышеизложенного Сращиваниеизurlадрес,Authorization
для вышеизложенного请求获取получатьизAuth
параметр,Content-CRC32
Получается путем вычисления содержимого файла.pythonПрочтите содержимое файла и посчитайтеcrc32кодследующее.
with open(filePath,"rb")as f:
data = f.read()
crc32 = hex(zlib.crc32(data) & 0xFFFFFFFF)[2:]
тело ответа
{
"code":2000, // Если возвращается 2000, загрузка прошла успешно.
"apiversion":"v1",
"message":"Success",
"data":{
"crc32":"ff3ceced"
}
}
#### Публикация графических работ
curl --location 'https://creator.douyin.com/web/api/media/aweme/create/' \
--header 'cookie: {Информация о файлах cookie для авторизации входа в систему}' \
--header 'user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 Edg/122.0.0.0' \
--header 'Content-Type: text/plain' \
--data 'text={заголовок}&text_extra=[]&activity=[]&challenges=[]&hashtag_source=""&mentions=[]&ifLongTitle=true&hot_sentence=&visibility_type=0&download=1&poster={storeUri}&timing=-1&images=[{"uri":"{storeUri}"]&creation_id=1hz6lvsn1710767057933'
В основном изменяйте параметры в --data,текст - это заголовок,imagesВнутри находится картинка и текст, которые вы хотите опубликовать.
storeUri
адресиз数组,posterЭто обложкаstoreUri
адрес
#### Загрузка фрагмента видео
Правила загрузки видеоресурсов примерно такие же, как и правила загрузки графических и текстовых ресурсов.,唯一из区别在于获取分配адресизparamsпараметри процесс шифрованияв
service
параметр Необходимо внести изменения,Изменения заключаются в следующем.
service = 'vod'
params = {
'Action': 'ApplyUploadInner',
'FileSize': fileSize, ## общий размер файла
'FileType': 'video',
'IsInner': '1',
'SpaceName': 'aweme',
'Version': '2020-11-19',
'app_id': '2906',
's': random_s,
'user_id': ''
}
Наконец, отправьте запрос на завершение загрузки видео. Код Python для нарезки видео реализован следующим образом:
def videoSplit(filePath, chunk_size=3):
chunk_size_bytes = chunk_size * 1024 * 1024
with open(filePath, 'rb') as file:
file_data = file.read()
total_slices = (len(file_data) + chunk_size_bytes - 1) // chunk_size_bytes
slices = []
chunks = {}
uploadid = str(uuid.uuid4())
for i in tqdm(range(total_slices), desc='ломтик'):
start = i * chunk_size_bytes
end = min((i + 1) * chunk_size_bytes, len(file_data))
data = file_data[start:end]
# Запрос информации о параметрах для каждого видео
slice_info = {
"uploadid": uploadid, # Загрузите uuid, uuid всего фрагмента видео должен быть единообразным.
'part_number': i + 1, # Порядок текущих фрагментов видео
'part_offset': start, # Адрес записи загруженного файла
"phase": "transfer",
}
chunks[start] = data
slices.append(slice_info)
return slices, chunks
На этом загрузка видеофрагмента завершена. Что касается выпуска видео, то я не буду здесь его дальше разбирать. Замена супа без замены лекарства - это процесс, если в процессе восстановления возникнут какие-либо проблемы или они есть. ошибки в тексте, пожалуйста, оставьте сообщение в области комментариев, чтобы добавить ответ как можно скорее.
#### Конечный эффект