Todos los productos
Search
Centro de documentos

Object Storage Service:(Recomendado) Firmas V4 en URL prefirmadas

Última actualización: Sep 24, 2026

Además de usar el encabezado HTTP Authorization para proporcionar la información de autenticación, puede generar una URL prefirmada que incluya una firma y otra información de solicitud obligatoria. Esto le permite otorgar acceso temporal a sus recursos de Object Storage Service (OSS) a terceros sin exponer sus credenciales de acceso. En este tema se describe cómo usar el algoritmo de firma V4 para crear una URL prefirmada.

Uso de los SDK de OSS para implementar firmas V4 automáticamente

Los SDK de OSS admiten la implementación automática de firmas V4. Se recomienda usar los SDK de OSS para iniciar las solicitudes, ya que así no es necesario calcular las firmas manualmente. Para obtener más información sobre la implementación de firmas en un lenguaje de programación específico, consulte el código de ejemplo del SDK de OSS correspondiente. A continuación se muestra una tabla con las referencias al código de ejemplo que se usa para firmar solicitudes mediante el algoritmo de firma V4 en los distintos SDK de OSS.

SDK

Ejemplo

Código de ejemplo

Java

Configure a client

OSSV4Signer.java

PHP

Configure a client

SignerV4.php

Node.js

Initialize OSS SDK for Node.js

signatureUrlV4.js

Browser.js

Initialization (Browser.js SDK)

Python

Initialization

auth.py

Go

Configure an OSSClient instance

v4.go

Objective-C

Initialization (iOS SDK)

OSSV4Signer.m

C++

Initialization (C++ SDK)

SignerV4.cc

C

Initialization (C SDK)

oss_auth.c

Firma de URL

  • Ejemplo

    https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject?x-oss-additional-headers=host&x-oss-credential=LTAI********************%2F20241203%2Fcn-hangzhou%2Foss%2Faliyun_v4_request&x-oss-date=20241203T034420Z&x-oss-expires=86400&x-oss-signature=70c542eaf652ac291c0c343d63ac24ede41c0526661d9d4c63c0906a2686160c&x-oss-signature-version=OSS4-HMAC-SHA256

    Para facilitar la lectura, los campos del parámetro x-oss-credential de la URL anterior están separados por barras diagonales (/). Cuando inicie una solicitud, codifique en URI las barras diagonales (/) de la URL para convertirlas en %2F. Por ejemplo:

    &x-oss-credential=LTAI********************%2F20241203%2Fcn-hangzhou%2Foss%2Faliyun_v4_request
  • Parámetros de cadena de consulta

    Parámetro

    Tipo

    Obligatorio

    Ejemplo

    Descripción

    x-oss-signature-version

    String

    Sí

    OSS4-HMAC-SHA256

    Versión y algoritmo de la firma. Establezca el valor en OSS4-HMAC-SHA256.

    x-oss-credential

    String

    Sí

    LTAI/20241203/cn-hangzhou/oss/aliyun_v4_request

    Credenciales que se usan para calcular la firma. Formato:

    LTAI********************/<date>/<region>/oss/aliyun_v4_request
    • AccessKeyId: ID de AccessKey del par de AccessKey.

    • date: fecha en la que se inició la solicitud.

    • region: región donde reside el recurso solicitado.

    • oss: nombre del servicio solicitado. Establezca el valor en oss.

    • aliyun_v4_request: descripción de la versión de firma en la solicitud. Establezca el valor en aliyun_v4_request.

    x-oss-date

    String

    Sí

    20241203T034420Z

    Hora en la que se firmó la URL. Sigue el estándar ISO 8601 y se muestra en UTC.

    Nota

    Esta hora se usa como marca de tiempo de la cadena que se va a firmar. El valor debe coincidir con el campo date de la clave de firma derivada.

    x-oss-expires

    Integer

    Sí

    3600

    Periodo de validez de la URL firmada. Se calcula a partir del valor del parámetro x-oss-date. Unidad: segundos.

    • Si usa un par de AccessKey, el valor debe estar entre 1 y 604,800 (7 días).

    • Si usa credenciales de acceso temporales obtenidas de Security Token Service (STS), el valor debe estar entre 1 y 43,200 (12 horas).

    Nota

    El momento en que OSS recibe la solicitud (T) debe cumplir el siguiente requisito: (x-oss-date - 15 minutos) ≤ T ≤ (x-oss-date + x-oss-expires).

    • Si T es anterior al valor (x-oss-date - 15 minutos), la solicitud no es válida.

    • Si la hora actual es posterior al valor (x-oss-date + x-oss-expires), la solicitud no es válida.

    x-oss-additional-headers

    String

    No

    host

    Encabezados que desea agregar para calcular la firma. Por ejemplo, puede agregar el encabezado host para evitar que se modifique el nombre de dominio desde el cual se inicia la solicitud.

    A continuación se describen los requisitos para construir un encabezado:

    • Todos los encabezados del parámetro x-oss-additional-headers deben estar en minúsculas.

    • Todos los encabezados del parámetro x-oss-additional-headers deben ordenarse alfabéticamente.

    • Todos los encabezados de una matriz se separan con punto y coma (;) para formar una cadena.

    x-oss-signature

    String

    Sí

    77Dv

    Descripción de la verificación de la firma. El parámetro x-oss-signature no se incluye en el cálculo de la firma.

    x-oss-security-token

    String

    No

    CAIS**

    Token de seguridad emitido por STS. Este parámetro es obligatorio solo cuando se usa un token de seguridad para calcular la firma de la URL.

Proceso de cálculo de la firma

image

El método para calcular la firma de una URL es similar al que se usa para calcular la firma del encabezado Authorization. A continuación se describen las diferencias entre ambos métodos:

  • El encabezado x-oss-content-sha256, que describe un hash de carga útil, no se usa para calcular la firma de una URL. Al crear una URL firmada, no es posible evaluar el contenido de la carga útil, por lo que se usa UNSIGNED-PAYLOAD.

  • Si una clave de los parámetros de cadena de consulta de una URL firmada coincide con un encabezado que se va a firmar, pero sus valores son distintos, se reporta un error. Si una clave tiene varios valores, todos se comparan al mismo tiempo. Se reporta un error si los valores difieren.

  • Si usa credenciales de acceso temporales obtenidas de STS para acceder a recursos de OSS mediante una URL firmada, debe agregar el parámetro x-oss-security-token a la cadena de consulta de la URL.

  • El parámetro x-oss-signature de la cadena de consulta no se incluye en el cálculo de la firma.

Paso 1: Crear una solicitud canónica

Convierta el contenido de su solicitud al formato canónico.

Formato

HTTP Verb + "\n" +
Canonical URI + "\n" +
Canonical Query String + "\n" +
Canonical Headers + "\n" +
Additional Headers + "\n" +
Hashed PayLoad

En la siguiente tabla se describen los parámetros anteriores.

Parámetro

Tipo

Obligatorio

Ejemplo

Descripción

HTTP Verb

Enumeration

Sí

GET

Método HTTP. Puede ser PUT, GET, POST, HEAD, DELETE u OPTIONS.

Nota

Canonical URI

String

Sí

/examplebucket/exampleobject

Cadena codificada en URI. No codifique la barra diagonal (/) de la ruta absoluta.

  • La URI comienza con una barra diagonal (/) después del nombre de dominio y llega hasta el final de la cadena si no se incluyen parámetros de cadena de consulta.

  • La URI comienza con una barra diagonal (/) después del nombre de dominio y termina con un signo de interrogación (?) si se incluyen parámetros de cadena de consulta.

A continuación se describe cómo especificar una URI canónica según los recursos incluidos en la URI de la solicitud:

  • Si la URI de la solicitud contiene tanto un nombre de bucket como un nombre de objeto, la URI canónica tiene el siguiente formato:

    /examplebucket/exampleobject.

  • Si la URI de la solicitud contiene solo un nombre de bucket, la URI canónica tiene el siguiente formato: /examplebucket/.

  • Si la URI de la solicitud contiene solo un nombre de objeto, la URI canónica se establece en /.

Canonical Query String

String

Sí

UriEncode("marker") + "=" + UriEncode("someMarker") + "&" + UriEncode("max-keys") + "=" + UriEncode("20") + "&" + UriEncode("prefix") + "=" + UriEncode("somePrefix")

Parámetros de cadena de consulta codificados en URI. Debe codificar en URI cada clave y valor de forma individual.

  • Ordene los parámetros de la cadena de consulta canónica alfabéticamente por nombre de clave después de codificarlos. Si existen claves idénticas, ordénelas cronológicamente según el momento en que se agregaron.

  • Si una clave no tiene valor, agregue solo la clave.

  • Si una solicitud no incluye una cadena de consulta, establezca la cadena de consulta canónica como una cadena vacía (""). Debe agregar un salto de línea al final.

  • Si una clave de los parámetros de cadena de consulta de una URL firmada coincide con un encabezado que se va a firmar, pero sus valores son distintos, se reporta un error. Si una clave tiene varios valores, todos se comparan al mismo tiempo. Se reporta un error si los valores difieren.

Canonical Headers

String

Sí

host:

examplebucket.oss-cn-hangzhou.aliyuncs.com

x-oss-content-sha256:

eee300fa39f52127a02af5f9bb86c0fd8b6776fc19101d9a6a7982c9d0edcc04

x-oss-date:

20241203T034420Z

Cadena que se obtiene al convertir la lista de encabezados de solicitud al formato canónico. Agregue un salto de línea al final de la cadena.

  • La clave y el valor de un encabezado se separan con dos puntos (:), y los encabezados se separan con un salto de línea.

  • Las claves de los encabezados deben estar en minúsculas y ordenarse alfabéticamente. Se deben eliminar los espacios iniciales y finales de los valores de los encabezados.

  • Las claves de los encabezados se ordenan alfabéticamente.

  • La hora de la solicitud se especifica mediante el encabezado x-oss-date. Sigue el estándar ISO 8601 y se muestra en UTC. Ejemplo: 20241203T034420Z.

  • El encabezado x-oss-content-sha256, que describe un hash de carga útil, no se usa para calcular la firma de una URL. Al crear una URL firmada, no es posible evaluar el contenido de la carga útil, por lo que se usa UNSIGNED-PAYLOAD.

Los encabezados canónicos (Canonical Headers) se dividen en dos tipos:

  • Los encabezados especificados por Additional Headers y usados para el cálculo de la firma.

  • Encabezados que deben agregarse a Canonical Headers si están presentes en la solicitud:

    • Content-Type

    • Content-MD5

    • x-oss-*

Additional Headers

String

Sí

content-length;host

Encabezados que desea agregar para calcular la firma. Todas las claves de los encabezados deben estar en minúsculas y ordenarse alfabéticamente.

Hashed PayLoad

String

Sí

UNSIGNED-PAYLOAD

Valor válido: UNSIGNED-PAYLOAD.

Ejemplo

"GET" | "GET" | ... + "\n" +
UriEncode(<Resource>) + "\n" +
UriEncode(<QueryParam1>) + "=" + UriEncode(<Value>) + "&" + UriEncode(<QueryParam2>) + "\n" +
Lowercase(<HeaderName1>) + ":" + Trim(<value>) + "\n" + Lowercase(<HeaderName2>) + ":" + Trim(<value>) + "\n" + "\n"
Lowercase(<AdditionalHeaderName1>) + ";" + Lowercase(<AdditionalHeaderName2>) + "\n" +
UNSIGNED-PAYLOAD

Paso 2: Crear una cadena para firmar

Concatene las siguientes cadenas para crear la cadena que se va a firmar.

Formato

"OSS4-HMAC-SHA256" + "\n" +
dateTimeStr + "\n" +
dateStr + "\n" +
DigestUtils.sha256Hex(canonicalRequest);

Ejemplo

String stringToSign = "OSS4-HMAC-SHA256\n" +
                dateTimeStr + "\n" +
                dateStr + "/cn-hangzhou/oss/aliyun_v4_request\n" +
                DigestUtils.sha256Hex(canonicalRequest);

En la siguiente tabla se describen los parámetros.

Parámetro

Tipo

Obligatorio

Archivo de ejemplo

Descripción

OSS4-HMAC-SHA256

Enumeration

Sí

OSS4-HMAC-SHA256

Algoritmo usado para crear el hash de la solicitud canónica. Establezca el valor en OSS4-HMAC-SHA256.

dateTimeStr

String

Sí

20241203T034420Z

Hora actual en UTC. Debe seguir el estándar ISO 8601.

dateStr

String

Sí

20241203/cn-hangzhou/oss/aliyun_v4_request

Información de ámbito. Restringe la firma calculada a la región y al servicio especificados. Formato:

<SignDate>/<Region>/oss/aliyun_v4_request

  • SignDate: fecha en la que se inicia la solicitud.

  • Region: región donde reside el recurso solicitado.

  • oss: nombre del servicio solicitado. Establezca el valor en oss.

  • aliyun_v4_request: descripción de la versión de firma en la solicitud. Establezca el valor en aliyun_v4_request.

CanonicalRequest

String

Sí

GET

/examplebucket/exampleobject

x-oss-additional-headers=host&x-oss-credential=LTAI%2F20241203%2Fcn-hangzhou%2Foss%2Faliyun_v4_request&x-oss-date=20241203T034420Z&x-oss-expires=86400&x-oss-signature-version=OSS4-HMAC-SHA256

host:examplebucket.oss-cn-hangzhou.aliyuncs.com

host

UNSIGNED-PAYLOAD

Cadena creada en el paso 1.

Paso 3: Calcular la firma

Cree una clave de firma y úsela para calcular la firma.

  1. Calcule la clave de firma.

    HMAC-SHA256(HMAC-SHA256(HMAC-SHA256(HMAC-SHA256("aliyun_v4" + accesskeysecret).getBytes(), dateStr), Region), "oss"), "aliyun_v4_request");
  2. Calcule la firma.

    BinaryUtil.toHex(HMAC-SHA256(SigningKey, StringToSign))

Código de ejemplo completo para obtener una URL firmada con V4

El siguiente código muestra un ejemplo de cómo calcular una firma V4 para generar una URL prefirmada para una solicitud GET. Esta URL prefirmada solo se puede usar para operaciones de descarga y acceso.

Importante

Cuando use el siguiente código de ejemplo, debe reemplazar las variables por los valores reales. Por ejemplo, sustituya Canonical URI por /examplebucket/exampleobject y Region por cn-hangzhou.

import com.aliyun.oss.common.utils.BinaryUtil;
import org.apache.commons.codec.digest.DigestUtils;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.net.URL;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.TimeZone;

public class Demo {

    /**
     * Signature calculation tool
     *
     * @return url
     */
    public static void main(String[] args) throws Exception {
        // Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured. 
        String accesskeyid =  System.getenv().get("OSS_ACCESS_KEY_ID");
        String accesskeysecret =  System.getenv().get("OSS_ACCESS_KEY_SECRET");
        // Query and display the current time. The time follows the ISO 8601 standard and is displayed in UTC.
        ZonedDateTime now = ZonedDateTime.now(TimeZone.getTimeZone("UTC").toZoneId());
        String dateStr = now.format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        String dateTimeStr = now.format(DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmss'Z'"));
        // Step 1: Create a canonical request. 
        String canonicalRequest =
                "GET\n" +
                        "/examplebucket/exampleobject\n" +
                        "x-oss-additional-headers=host&x-oss-credential=" + accesskeyid + "%2F" + dateStr + "%2Fcn-hangzhou%2Foss%2Faliyun_v4_request&x-oss-date=" + dateTimeStr + "&x-oss-expires=86400&x-oss-signature-version=OSS4-HMAC-SHA256\n" +
                        "host:examplebucket.oss-cn-hangzhou.aliyuncs.com\n" +
                        "\n" +
                        "host\n" +
                        "UNSIGNED-PAYLOAD";
        System.out.println("canonicalRequest:" + canonicalRequest);
        // Step 2: Create a string to sign. 
        String stringToSign = "OSS4-HMAC-SHA256\n" +
                dateTimeStr + "\n" +
                dateStr + "/cn-hangzhou/oss/aliyun_v4_request\n" +
                DigestUtils.sha256Hex(canonicalRequest);

        // Step 3: Calculate the signature. 
        byte[] dateKey = hmacsha256(("aliyun_v4" + accesskeysecret).getBytes(), dateStr);
        byte[] dateRegionKey = hmacsha256(dateKey, "cn-hangzhou");
        byte[] dateRegionServiceKey = hmacsha256(dateRegionKey, "oss");
        byte[] signingKey = hmacsha256(dateRegionServiceKey, "aliyun_v4_request");

        byte[] result = hmacsha256(signingKey, stringToSign);
        String signature = BinaryUtil.toHex(result);
        System.out.println("signature:" + signature);

        // Step 4: Add the signature to the URL. 
        String resourcePath = "exampleobject";
        String endpoint = "https://examplebucket.oss-cn-hangzhou.aliyuncs.com";
        String queryString = "x-oss-additional-headers=host&" +
                "x-oss-credential=" + accesskeyid + "%2F" + dateStr + "%2Fcn-hangzhou%2Foss%2Faliyun_v4_request&" +
                "x-oss-date=" + dateTimeStr + "&" +
                "x-oss-expires=86400&" +
                "x-oss-signature=" + signature + "&" +
                "x-oss-signature-version=OSS4-HMAC-SHA256";

        String urlStr = endpoint + "/" + resourcePath + "?" + queryString;
        URL url = new URL(urlStr);
        System.out.println("url:" + url);
    }

    public static byte[] hmacsha256(byte[] key, String data) {
        try {
            // Initialize the HMAC key specifications, set the algorithm to HMAC-SHA256, and use the provided key. 
            SecretKeySpec secretKeySpec = new SecretKeySpec(key, "HmacSHA256");

            // Obtain a Mac instance and use the getInstance method to set the algorithm to HMAC-SHA256. 
            Mac mac = Mac.getInstance("HmacSHA256");
            // Use the key to initialize the Mac instance. 
            mac.init(secretKeySpec);

            // Calculate the HMAC. Use the doFinal method to process the data and return the result as a byte array. 
            byte[] hmacBytes = mac.doFinal(data.getBytes());

            return hmacBytes;
        } catch (Exception e) {
            throw new RuntimeException("Failed to calculate HMAC-SHA256", e);
        }
    }
}

Salida de ejemplo:

signature:eee300fa39f52127a02af5f9bb86c0fd8b6776fc19101d9a6a7982c9d0edcc04
url:https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject?x-oss-additional-headers=host&x-oss-credential=LTAI********************%2F20241203%2Fcn-hangzhou%2Foss%2Faliyun_v4_request&x-oss-date=20241203T032307Z&x-oss-expires=86400&x-oss-signature=eee300fa39f52127a02af5f9bb86c0fd8b6776fc19101d9a6a7982c9d0edcc04&x-oss-signature-version=OSS4-HMAC-SHA256

Referencias