Yandex Cloud
Поиск
Связаться с намиПодключиться
  • Документация
  • Блог
  • Все сервисы
  • Статус работы сервисов
    • Популярные
    • Инфраструктура и сеть
    • Платформа данных
    • Контейнеры
    • Инструменты разработчика
    • Бессерверные вычисления
    • Безопасность
    • Мониторинг и управление ресурсами
    • Машинное обучение
    • Бизнес-инструменты
  • Все решения
    • По отраслям
    • По типу задач
    • Экономика платформы
    • Безопасность
    • Техническая поддержка
    • Каталог партнёров
    • Обучение и сертификация
    • Облако для стартапов
    • Облако для крупного бизнеса
    • Центр технологий для общества
    • Облако для интеграторов
    • Поддержка IT-бизнеса
    • Облако для фрилансеров
    • Обучение и сертификация
    • Блог
    • Документация
    • Контент-программа
    • Мероприятия и вебинары
    • Контакты, чаты и сообщества
    • Идеи
    • Истории успеха
    • Тарифы Yandex Cloud
    • Промоакции и free tier
    • Правила тарификации
  • Документация
  • Блог
Проект Яндекса
© 2025 ООО «Яндекс.Облако»
Yandex Object Storage
    • Обзор
    • Identity and Access Management
    • Список управления доступом (ACL)
    • Политика доступа (Bucket Policy)
    • Публичный доступ
    • Подписанные (pre-signed) URL
    • Security Token Service
  • Справочник Terraform
  • Метрики Monitoring
  • Аудитные логи Audit Trails
  • Логи бакета
  • История изменений
  • Вопросы и ответы
  • Обучающие курсы

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

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

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

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

В 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")
    

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

Чтобы получить подпись строки, необходимо использовать механизм 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. Примеры с использованием AWS SDK и прочих инструментов см. в подразделе Примеры получения подписанной ссылки в инструментах Object Storage.

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>';

?>

Примеры получения подписанной ссылки в инструментах Object StorageПримеры получения подписанной ссылки в инструментах Object Storage

В подразделе приведены примеры генерации подписанных URL c помощь различных инструментов Object Storage.

Консоль управления
AWS CLI
Python (boto3)
JavaScript
  1. В консоли управления выберите каталог.
  2. Выберите сервис Object Storage.
  3. Нажмите на имя необходимого бакета.
  4. Нажмите на имя объекта.
  5. Нажмите Получить ссылку в правом верхнем углу.
  6. Для бакета с ограниченным доступом укажите Время жизни ссылки в часах или днях (максимум 30 дней).
  7. Нажмите Получить ссылку.
  8. Скопируйте полученную ссылку.

Ссылку на скачивание объекта можно сгенерировать с помощью AWS CLI. Для этого выполните команду:

aws s3 presign s3://<имя_бакета>/<ключ_объекта> \
  --expires-in <время_жизни_ссылки> \
  --endpoint-url "https://storage.yandexcloud.net/"

Чтобы ссылка сформировалась корректно, обязательно укажите параметр --endpoint-url с указанием на доменное имя Object Storage. Подробнее см. в разделе об особенностях работы AWS CLI.

Пример генерирует подписанный URL для скачивания объекта object-for-share из бакета bucket-with-objects. URL действителен в течение 100 секунд.

# coding=utf-8

import boto3
from botocore.client import Config


ENDPOINT = "https://storage.yandexcloud.net"

ACCESS_KEY = "JK38EXAMP********"
SECRET_KEY = "ExamP1eSecReTKeykdo********"

session = boto3.Session(
    aws_access_key_id=ACCESS_KEY,
    aws_secret_access_key=SECRET_KEY,
    region_name="ru-central1",
)
s3 = session.client(
    "s3", endpoint_url=ENDPOINT, config=Config(signature_version="s3v4")
)

presigned_url = s3.generate_presigned_url(
    "get_object",
    Params={"Bucket": "bucket-with-objects", "Key": "object-for-share"},
    ExpiresIn=100,
)

print(presigned_url)

В примерах ниже используются библиотеки @aws-sdk/client-s3 и @aws-sdk/s3-request-presigner.

  • Скачивание объекта

    Пример генерирует подписанный URL для скачивания объекта object-for-share из бакета bucket-with-objects. URL действителен в течение 100 секунд.

    import { S3Client, GetObjectCommand } from "@aws-sdk/client-s3";
    import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
    
    const S3_ENDPOINT = "https://storage.yandexcloud.net";
    
    const ACCESS_KEY_ID = "JK38EXAMP********";
    const SECRET_ACCESS_KEY = "ExamP1eSecReTKeykdo********";
    
    const s3Client = new S3Client({
      region: "ru-central1",
      endpoint: S3_ENDPOINT,
      credentials: {
        accessKeyId: ACCESS_KEY_ID,
        secretAccessKey: SECRET_ACCESS_KEY,
      },
    });
    
    const command = new GetObjectCommand({
      Bucket: "bucket-with-objects",
      Key: "object-for-share",
    });
    const objectPresignedUrl = await getSignedUrl(s3Client, command, {
      expiresIn: 100,
    });
    
    console.log(objectPresignedUrl);
    
  • Загрузка объекта

    Пример генерирует подписанный URL для загрузки объекта object-for-share в бакет bucket-with-objects. URL действителен в течение 100 секунд.

    import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";
    import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
    
    const S3_ENDPOINT = "https://storage.yandexcloud.net";
    
    const ACCESS_KEY_ID = "JK38EXAMP********";
    const SECRET_ACCESS_KEY = "ExamP1eSecReTKeykdo********";
    
    const s3Client = new S3Client({
      region: "ru-central1",
      endpoint: S3_ENDPOINT,
      credentials: {
        accessKeyId: ACCESS_KEY_ID,
        secretAccessKey: SECRET_ACCESS_KEY,
      },
    });
    
    const command = new PutObjectCommand({
      Bucket: "bucket-with-objects",
      Key: "object-for-share",
    });
    const objectPresignedUrl = await getSignedUrl(s3Client, command, {
      expiresIn: 100,
    });
    
    console.log(objectPresignedUrl);
    

Примеры использованияПримеры использования

  • Организация защищенного доступа к контенту в Cloud CDN

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

Предыдущая
Публичный доступ
Следующая
Security Token Service
Проект Яндекса
© 2025 ООО «Яндекс.Облако»