Yandex Cloud
Поиск
Связаться с экспертомПопробовать бесплатно
  • Кейсы
  • Документация
  • Блог
  • Все сервисы
  • Статус работы сервисов
  • Marketplace
    • Популярные
    • Инфраструктура и сеть
    • Платформа данных
    • Искусственный интеллект
    • Безопасность
    • Инструменты DevOps
    • Бессерверные вычисления
    • Управление ресурсами
  • Все решения
    • По отраслям
    • По типу задач
    • Экономика платформы
    • Безопасность
    • Техническая поддержка
    • Каталог партнёров
    • Обучение и сертификация
    • Облако для стартапов
    • Облако для крупного бизнеса
    • Центр технологий для общества
    • Облако для интеграторов
    • Поддержка IT-бизнеса
    • Облако для фрилансеров
    • Обучение и сертификация
    • Блог
    • Документация
    • Контент-программа
    • Мероприятия и вебинары
    • Контакты, чаты и сообщества
    • Идеи
    • Калькулятор цен
    • Тарифы
    • Акции и free tier
  • Кейсы
  • Документация
  • Блог
Создавайте контент и получайте гранты!Готовы написать своё руководство? Участвуйте в контент-программе и получайте гранты на работу с облачными сервисами!
Подробнее о программе
Проект Яндекса
© 2026 ООО «Яндекс.Облако»
Yandex Object Storage
    • Обзор
    • Бакет
    • Объект
    • Версионирование бакета
    • Блокировка версии объекта (object lock)
    • Частичное изменение объекта
    • Шифрование
    • Жизненные циклы объектов
    • CORS
    • Хостинг статических сайтов
    • Подписанные (pre-signed) URL
    • Составная (multipart) загрузка
    • Список управления доступом (ACL)
    • Политика доступа (Bucket Policy)
    • Загрузка файла через HTML-форму
    • Класс хранилища
    • Выгрузка метаданных объектов
    • Механизм логирования действий с бакетом
    • Резервное копирование
    • Протокол TLS
    • Метки
    • Язык запросов S3 Select
    • Квоты и лимиты
  • Правила тарификации
  • Справочник Terraform
  • Метрики Monitoring
  • Аудитные логи Audit Trails
  • Логи бакета
  • История изменений
  • Вопросы и ответы
  • Обучающие курсы

В этой статье:

  • Общий вид подписанного URL
  • Составление подписанного URL
  • Канонический запрос
  • Строка для подписи
  • Подписывающий ключ
  • Подпись строки с помощью ключа
  • Подписанный URL
  1. Концепции
  2. Подписанные (pre-signed) URL

Подписанные (pre-signed) URL

Статья создана
Yandex Cloud
Улучшена
Обновлена 23 апреля 2026 г.
  • Общий вид подписанного URL
  • Составление подписанного URL
    • Канонический запрос
    • Строка для подписи
    • Подписывающий ключ
    • Подпись строки с помощью ключа
    • Подписанный URL

В Object Storage реализовано несколько механизмов для управления доступом к ресурсам. Алгоритм взаимодействия этих механизмов см. в Обзор способов управления доступом в Object Storage.

С помощью подписанных URL произвольный пользователь интернета может выполнять в Object Storage различные операции, например:

  • Скачать объект.
  • Загрузить объект.
  • Создать бакет.

Подписанный URL — это URL, содержащий в своих параметрах данные для авторизации запроса. Составить подписанный URL может пользователь, обладающий статическими ключами доступа.

Раздел содержит общие принципы построения подписанного URL с использованием AWS Signature V4.

Примечание

SDK для различных языков программирования и другие инструменты для работы с AWS S3 содержат готовые методы генерирования подписанного URL, которые можно использовать и для Object Storage.

Общий вид подписанного URLОбщий вид подписанного URL

https://<имя_бакета>.storage.yandexcloud.net/<ключ_объекта>?
     X-Amz-Algorithm=AWS4-HMAC-SHA256
    &X-Amz-Credential=<access_key-id>%2F<YYYYMMDD>%2Fru-central1%2Fs3%2Faws4_request
    &X-Amz-Date=<время_в_формате_ISO_8601>
    &X-Amz-Expires=<время_жизни_ссылки>
    &X-Amz-SignedHeaders=<список_подписанных_заголовков>
    &X-Amz-Signature=<подпись>

Параметры подписанного URL:

Параметр Описание
X-Amz-Algorithm Идентифицирует версию подписи и алгоритм ее вычисления. Значение — AWS4-HMAC-SHA256.
X-Amz-Credential Идентификатор для подписи.

Строка формата <access-key-id>/<YYYYMMDD>/ru-central1/s3/aws4_request, где <YYYYMMDD> должна совпадать с датой, установленной в заголовке X-Amz-Date.
X-Amz-Date Время в формате ISO8601, например, 20180719T000000Z. Указанная дата должна по значению (не по формату) совпадать с датой в параметре X-Amz-Credential.
X-Amz-Expires Время в секундах, в течение которого ссылка действительна. Начало отсчета — момент, указанный в X-Amz-Date. Максимальное значение — 2592000 секунд (30 дней).
X-Amz-SignedHeaders Заголовки запроса, которые вы хотите подписать, разделенные точкой с запятой (;).

Обязательно подписывайте заголовок Host и все заголовки X-Amz-*, которые используются в запросе. Другие заголовки подписывать не обязательно, однако чем больше вы подпишете заголовков, тем безопаснее будет запрос.
X-Amz-Signature Подпись запроса.

Составление подписанного URLСоставление подписанного URL

Примечание

Для публичных бакетов необязательно генерировать подписанные ссылки. Из бакета с публичным доступом файлы можно получить как по протоколу HTTP, так и по протоколу HTTPS, даже если для бакета не настроен хостинг сайта.

Чтобы получить подписанный URL:

  1. Составьте канонический запрос.
  2. Составьте строку для подписи.
  3. Сформируйте подписывающий ключ.
  4. Вычислите подпись с помощью ключа.
  5. Сформируйте подписанный URL.

Для составления подписанного URL необходимо обладать статическими ключами доступа.

Канонический запросКанонический запрос

Общий вид канонического запроса:

<HTTPVerb>\n
<CanonicalURL>\n
<CanonicalQueryString>\n
<CanonicalHeaders>\n
<SignedHeaders>\n
UNSIGNED-PAYLOAD

HTTPVerbHTTPVerb

HTTP метод, которым будет отправлен запрос: GET, PUT, HEAD или DELETE.

CanonicalURLCanonicalURL

URL-кодированный ключ объекта. Например, /folder/object.ext.

Примечание

Не нормализуйте путь. Например, объект может иметь ключ some//strange//key//example и нормализация пути /<bucket-name>/some/strange/key/example сделает ключ некорректным.

CanonicalQueryStringCanonicalQueryString

Каноническая строка запроса должна включать все query параметры конечного URL, кроме X-Amz-Signature. Параметры в строке должны быть URL-кодированы и отсортированы по алфавиту.

Пример:

X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=JK38EXAMPLEAKDID8%2F20190801%2Fru-central1%2Fs3%2Faws4_request&X-Amz-Date=20190801T000000Z&X-Amz-Expires=86400&X-Amz-SignedHeaders=host

CanonicalHeadersCanonicalHeaders

Список заголовков запроса со значениями.

Требования:

  • Каждый заголовок отделяется символом новой строки \n.
  • Имена заголовков должны быть в нижнем регистре.
  • Заголовки должны быть отсортированы по алфавиту.
  • Не должно быть лишних пробелов.
  • Список должен содержать заголовок host и все заголовки x-amz-*, которые используются в запросе.

Дополнительно в список можно добавить любой из заголовков запроса. Чем больше вы подпишете заголовков, тем безопаснее будет запрос.

Пример:

host:sample-bucket.storage.yandexcloud.net
x-amz-date:20190801T000000Z

SignedHeadersSignedHeaders

Список имен заголовков запроса в нижнем регистре, отсортированный по алфавиту и разделенный точками с запятыми.

Пример:

host;x-amz-date

Завершение канонического запросаЗавершение канонического запроса

Завершать канонический запрос всегда должна строка UNSIGNED-PAYLOAD.

Строка для подписиСтрока для подписи

Общий вид строки для подписи:

"AWS4-HMAC-SHA256" + "\n" +
<timestamp> + "\n" +
<scope> + "\n" +
Hex(Hash-SHA256(<CanonicalRequest>))

Где:

  • AWS4-HMAC-SHA256 — алгоритм хэширования.
  • timestamp — текущее время в формате ISO 8601, например, 20190801T000000Z. Указанная дата должна по значению (не по формату) совпадать с датой в scope.
  • scope — <YYYYMMDD>/ru-central1/s3/aws4_request.
  • CanonicalRequest — сформированный ранее канонический запрос. В строку для подписи помещается SHA256-хэш канонического запроса в шестнадцатеричном представлении.

Подписывающий ключПодписывающий ключ

Чтобы сгенерировать подписывающий ключ:

  1. Закодируйте дату с помощью секретного ключа:

    DateKey = sign("AWS4" + "SecretKey", "yyyymmdd")
    
  2. Закодируйте регион с помощью полученного на предыдущем шаге ключа DateKey:

    RegionKey = sign(DateKey, "ru-central1")
    
  3. Закодируйте сервис с помощью полученного на предыдущем шаге ключа RegionKey:

    ServiceKey = sign(RegionKey, "s3")
    
  4. Получите подписывающий ключ:

    SigningKey = sign(ServiceKey, "aws4_request")
    

Примечание

Подписывающий ключ действителен в течение нескольких минут, после этого его использование может привести к ошибке 403 — RequestTimeTooSkewed. Регулярно обновляйте подписывающий ключ, чтобы продлить его срок действия.

Для генерации подписывающего ключа AWS SDK использует локальное системное время.

Если локальное системное время некорректно

Вы можете использовать функцию получения реального времени, например v4.SignSDKRequestWithCurrentTime в AWS SDK для Go:

client := s3.New(sess)
client.Handlers.Sign.Swap(v4.SignRequestHandler.Name, request.NamedHandler{
    Name: v4.SignRequestHandler.Name,
    Fn: func(r *request.Request) {
        v4.SignSDKRequestWithCurrentTime(r, currentTimeFn)
    },
})

Подпись строки с помощью ключаПодпись строки с помощью ключа

Чтобы получить подпись строки, необходимо использовать механизм HMAC с хэширующей функцией SHA256, а полученный результат преобразовать в шестнадцатеричное представление.

signature = Hex(sign(SigningKey, StringToSign))

Подписанный URLПодписанный URL

Чтобы составить подписанный URL, к URL ресурса Object Storage добавьте параметры, необходимые для авторизации запроса, в том числе параметр X-Amz-Signature с вычисленной подписью в значении.

Значения остальных параметров должны совпадать с аналогичными значениями, указанными ранее в каноническом запросе и в строке для подписи.

Пример составления подписанного URL для скачивания объектаПример составления подписанного URL для скачивания объекта

Составим подписанный URL для скачивания объекта object-for-share.txt из бакета в течение часа:

  • Статический ключ:

    access_key_id = 'JK38EXAMP********'
    secret_access_key = 'ExamP1eSecReTKeykdo********'
    
  • Канонический запрос:

    GET
    /object-for-share.txt
    X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=YCAJEK0Iv6x********eLTAdg%2F20231208%2Fru-central1%2Fs3%2Faws4_request&X-Amz-Date=20231208T184504Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host 
    host:<имя_бакета>.storage.yandexcloud.net
    
    host
    UNSIGNED-PAYLOAD
    
  • Строка для подписи:

    AWS4-HMAC-SHA256
    20231208T184504Z
    20231208/ru-central1/s3/aws4_request
    e823d75aad02c1317589bd5373fe9e20d5ef44499237703ff23e5600********
    
  • Подписывающий ключ:

    sign(sign(sign(sign("AWS4" + "ExamP1eSecReTKeykdokKK38800","20190801"),"ru-central1"),"s3"),"aws4_request")
    

    Функция sign введена для обозначения способа вычисления ключа с помощью механизма HMAC с хэширующей функцией SHA256.

  • Подпись:

    b10c16a1997bb524bf59974512f1a6561cf2953c29dc3efbdb920790********
    
  • Подписанный URL:

    https://<имя_бакета>.storage.yandexcloud.net/object-for-share.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=YCAJEK0Iv6xqy-pEQcueLTAdg%2F20231208%2Fru-central1%2Fs3%2Faws4_request&X-Amz-Date=20231208T195434Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=b10c16a1997bb524bf59974512f1a6561cf2953c29dc3efbdb920790********
    

Отрабатывать процесс формирования запроса и подписи вы можете с помощью AWS CLI в режиме отладки.

Чтобы отправить подписанный запрос к S3 API, вы можете использовать утилиту curl.

Примеры кода для генерации подписанных URLПримеры кода для генерации подписанных URL

В подразделе приведены примеры кода для генерации подписанных URL.

Чтобы показать принцип формирования и подписи запросов к Object Storage, в этих примерах не используются AWS SDK. Примеры с использованием Yandex Cloud CLI, AWS CLI и AWS SDK см. на страницах:

  • Получение подписанной ссылки (pre-signed URL) на скачивание объекта
  • Получение подписанной ссылки (pre-signed URL) на загрузку объекта
Python
PHP
import datetime
import hashlib
import hmac

access_key = '<идентификатор_статического_ключа>'
secret_key = '<содержимое_статического_ключа>'
object_key = '<ключ_объекта>'
bucket = '<имя_бакета>'
host = 'storage.yandexcloud.net'
now = datetime.datetime.now(datetime.UTC)
datestamp = now.strftime('%Y%m%d')
timestamp = now.strftime('%Y%m%dT%H%M%SZ')

def sign(key, msg):
    return hmac.new(key, msg.encode('utf-8'), hashlib.sha256).digest()

canonical_request = """GET
/{bucket}/{object_key}
X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential={access_key}%2F{datestamp}%2Fru-central1%2Fs3%2Faws4_request&X-Amz-Date={timestamp}&X-Amz-Expires=3600&X-Amz-SignedHeaders=host
host:{host}

host
UNSIGNED-PAYLOAD""".format(
    bucket=bucket,
    object_key=object_key,
    access_key=access_key,
    datestamp=datestamp,
    timestamp=timestamp,
    host=host)

print()
print("Canonical request:\n" + canonical_request)
print()

string_to_sign = """AWS4-HMAC-SHA256
{timestamp}
{datestamp}/ru-central1/s3/aws4_request
{request_hash}""".format(
    timestamp=timestamp,
    datestamp=datestamp,
    request_hash=hashlib.sha256(canonical_request.encode('utf-8')).hexdigest())

print()
print("String to be signed:\n" + string_to_sign)
print()

signing_key = sign(sign(sign(sign(('AWS4' + secret_key).encode('utf-8'), datestamp), 'ru-central1'), 's3'), 'aws4_request')
signature = hmac.new(signing_key, string_to_sign.encode('utf-8'), hashlib.sha256).hexdigest()

print()
print("Signature: " + signature)
print()

signed_link = "https://" + host + '/' + bucket + '/' + object_key + "?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=" + access_key + "%2F" + datestamp + "%2Fru-central1%2Fs3%2Faws4_request&X-Amz-Date=" + timestamp + "&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=" + signature + "\n"

print()
print("Signed Link:\n" + signed_link)
<?php

  date_default_timezone_set('UTC');
  $keyid = "<идентификатор_статического_ключа>";
  $secretkey = "<содержимое_статического_ключа>";
  $path = "<ключ_объекта>";
  $objectname = "/".implode("/", array_map("rawurlencode", explode("/", $path)));
  $host = "<имя_бакета>.storage.yandexcloud.net";
  $region = "ru-central1";
  $timestamp = time();
  $dater = strval(date('Ymd', $timestamp));
  $dateValue = strval(date('Ymd', $timestamp))."T".strval(date('His', $timestamp))."Z";

  // Generate the canonical request
  $canonical_request = "GET\n".$objectname."\nX-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=".$keyid."%2F".$dater."%2Fru-central1%2Fs3%2Faws4_request&X-Amz-Date=".$dateValue."&X-Amz-Expires=3600&X-Amz-SignedHeaders=host\nhost:".$host."\n\nhost\nUNSIGNED-PAYLOAD";

  echo "<b>Canonical request: </b><br>".$canonical_request."<br><br>";

  // Generate the string to be signed
  $string_to_sign = "AWS4-HMAC-SHA256\n".$dateValue."\n".$dater."/".$region."/s3/aws4_request\n".openssl_digest($canonical_request, "sha256", $binary = false);

  echo "<b>String to be signed: </b><br>".$string_to_sign."<br><br>";

  // Generate the signing key
  $signing_key = hash_hmac('sha256', 'aws4_request', hash_hmac('sha256', 's3', hash_hmac('sha256', 'ru-central1', hash_hmac('sha256', $dater, 'AWS4'.$secretkey, true), true), true), true);

  echo "<b>Signing key: </b><br>".$signing_key."<br><br>";

  // Generate the signature
  $signature = hash_hmac('sha256', $string_to_sign, $signing_key);

  echo "<b>Signature: </b><br>".$signature."<br><br>";

  // Generate the pre-signed link
  $signed_link = "https://".$host.$objectname."?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=".$keyid."%2F".$dater."%2Fru-central1%2Fs3%2Faws4_request&X-Amz-Date=".$dateValue."&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=".$signature."\n";

  echo '<b>Signed link: </b><br>'.'<a href = "'.$signed_link.'" target = "_blank">'.$signed_link.'</a>';

?>

Была ли статья полезна?

Предыдущая
Хостинг статических сайтов
Следующая
Составная (multipart) загрузка
Создавайте контент и получайте гранты!Готовы написать своё руководство? Участвуйте в контент-программе и получайте гранты на работу с облачными сервисами!
Подробнее о программе
Проект Яндекса
© 2026 ООО «Яндекс.Облако»