Firmas

Las firmas son un método para autenticar las solicitudes que se envían a la API de XML de Cloud Storage. Las firmas se usan, por ejemplo, cuando se trabaja con URL firmadas o formularios de HTML. Esta página se aplica a las firmas creadas mediante el proceso de firma de V4, que es el proceso recomendado para crear firmas.

Descripción general

Las Firmas proporcionan identidad y autenticación sólida, lo que garantiza que las solicitudes a Cloud Storage se procesen mediante la autoridad de una cuenta específica. Las firmas logran tal autenticación sin revelar la información sensible de clave, llamada secretos o claves privadas, asociada con esa cuenta.

Cuando realizas una solicitud con una firma, Cloud Storage usa su copia de la información de claves a fin de calcular una firma equivalente para la solicitud. Si la firma incluida en la solicitud coincide con la firma que calcula Cloud Storage, este sabrá que la firma se creó mediante el secreto o clave privada relevante.

En Cloud Storage, las firmas deben usarse cuando se trabaja con lo siguiente:

Además, las firmas se pueden usar para realizar lo siguiente:

  • Solicitudes directas firmadas a la API de XML

Usar firmas en solicitudes directas es útil cuando se realizan migraciones simples desde Amazon S3. Sin embargo, el flujo de autenticación recomendado para las solicitudes directas es usar tokens de OAuth 2.0.

Estructura

Los componentes y el proceso para crear una firma dependen del uso que le des y de la clave de autenticación con la que trabajes. En términos generales, una firma tiene dos componentes: la clave de firma y la información de la solicitud. Aplicas un algoritmo de firma a estos dos componentes para crear la firma. En la siguiente tabla, se resumen los diferentes casos prácticos para las firmas y los componentes que necesitas en cada caso a fin de construir la firma:

Caso práctico Clave de firma Información de solicitud
Formulario HTML con una clave RSA Usa directamente la clave privada RSA Documento de políticas codificado en Base64
Formulario HTML con una clave HMAC Deriva a partir del secreto de la clave HMAC Documento de políticas codificado en Base64
URL firmada o solicitud firmada con una clave RSA Usa directamente la clave privada RSA String para firmar
URL firmada o solicitud firmada con una clave HMAC Deriva a partir del secreto de la clave HMAC String para firmar

String para firmar

Una string para firmar incluye metainformación sobre la solicitud y un hash de la solicitud canónica que deseas firmar.

Estructura

Una string para firmar debe estar codificada en UTF-8 y tener la siguiente estructura, incluido el uso de líneas nuevas entre cada elemento:

SIGNING_ALGORITHM
ACTIVE_DATETIME
CREDENTIAL_SCOPE
HASHED_CANONICAL_REQUEST

Algoritmo de firma

El valor de SIGNING_ALGORITHM depende del tipo de clave que usas y las extensiones de tus encabezados o parámetros de consulta:

Caso práctico Valor de SIGNING_ALGORITHM
Extensiones x-goog-* y una clave RSA GOOG4-RSA-SHA256
Extensiones x-goog-* y una clave HMAC GOOG4-HMAC-SHA256
Extensiones x-amz-* y una clave HMAC AWS4-HMAC-SHA256

Fecha y hora activas

La fecha y hora en que se puede usar la firma en el formato básico YYYYMMDD'T'HHMMSS'Z' de ISO 8601.

  • En el caso de las URL firmadas, la firma se puede usar desde 15 minutos antes de la fecha y hora activas hasta la hora de vencimiento que especifiques. La fecha y hora activas deben coincidir con el parámetro de la cadena de consulta X-Goog-Date de la URL firmada y debe usar el mismo día que especifiques en el alcance de la credencial.

  • Para las solicitudes firmadas, la firma se puede usar desde 15 minutos antes de la fecha y hora activas hasta 15 minutos después. La fecha y hora activas deben coincidir con el encabezado de la solicitud x-goog-date de la solicitud firmada y debe usarse el mismo día que se especifique en el alcance de la credencial.

Alcance de la credencial

El alcance de la credencial para la solicitud.

Hash de la solicitud canónica

El hash SHA-256 con codificación hexadecimal de una solicitud canónica. Usa una función de hash SHA-256 para crear un valor de hash de la solicitud canónica. El lenguaje de programación debe tener una biblioteca para crear hash SHA-256. A continuación, se muestra un ejemplo de cómo se ve un valor de hash:

436b7ce722d03b17d3f790255dd57904f7ed61c02ac5127a0ca8063877e4e42c

Ejemplo

A continuación, se muestra un ejemplo de una string para firmar formada de manera adecuada, con líneas nuevas que se muestran como líneas nuevas reales y no como \n:

GOOG4-RSA-SHA256
20191201T190859Z
20191201/us-central1/storage/goog4_request
54f3076005db23fbecdb409d25c0ccb9fb8b5e24c59f12634654c0be13459af0

Documento de políticas

Un documento de políticas define lo que los usuarios con acceso al formulario HTML correspondiente pueden subir a Cloud Storage. Un documento de políticas proporciona autorización para garantizar que el formulario HTML pueda subir archivos al bucket de destino. Puedes usar documentos de políticas para permitir que los visitantes de un sitio web suban archivos a Cloud Storage.

Se crea un documento de políticas en JavaScript Object Notation (JSON). El documento de política debe estar codificado en UTF-8 y Base64. Un documento de políticas contiene las siguientes secciones:

Entrada Descripción
expiration La fecha de vencimiento del documento de políticas, en el formato básico YYYYMMDD'T'HHMMSS'Z' de ISO 8601. Un documento de políticas vencido hace que el formulario HTML se rompa.
conditions Un arreglo de condiciones que se deben cumplir en cada carga.

La sección conditions debe incluir lo siguiente:

  • Una declaración de condición para cada campo que uses en tu formulario HTML, excepto los campos x-goog-signature, file y policy.

  • Una declaración de condición "bucket", incluso si no usas el campo de depósito en tu formulario HTML.

Si deseas usar varias declaraciones de condiciones en el mismo campo, debes crear un formulario HTML separado para cada una. Se pueden usar tres tipos de condiciones en las declaraciones:

  • Concordancia exacta

    Realiza una concordancia exacta para un campo. El valor usado en el campo especificado del formulario HTML debe coincidir con el valor establecido en esta condición. Establece esta condición mediante uno de los siguientes estilos de sintaxis:

    {"field" : "value"}
    ["eq", "$field", "value"]

    Todos los campos de formularios HTML válidos, excepto Content-Length, pueden usar concordancias exactas.

  • Comienza con

    Si el valor de un campo debe comenzar con un prefijo determinado, usa la condición starts-with con la siguiente sintaxis:

    ["starts-with", "$field", "value"]

    Si el valor de un campo no tiene restricciones, usa la condición starts-with con la siguiente sintaxis:

    ["starts-with", "$field", ""]

    Todos los campos de formulario HTML válidos, excepto Content-Length, pueden usar la condición starts-with.

  • Rango de longitud del contenido

    Especifica un rango de valores aceptables que se pueden usar en el campo Content-Length. Especifica esta condición con la siguiente sintaxis:

    ["content-length-range", min_range, max_range]

Ejemplo

A continuación, se muestra un ejemplo de un documento de políticas:

{"expiration": "2020-06-16T11:11:11Z",
 "conditions": [
  ["starts-with", "$key", ""],
  {"bucket": "travel-maps"},
  {"success_action_redirect": "http://www.example.com/success_notification.html"},
  ["eq", "$Content-Type", "image/jpeg"],
  ["content-length-range", 0, 1000000],
  {"x-goog-algorithm": "GOOG4-RSA-SHA256"},
  {"x-goog-credential": "example_account@example_project.iam.gserviceaccount.com/20191102/us-central1/storage/goog4_request"},
  {"x-goog-date": "20191102T043530Z"}
  ]
}

Este documento de políticas define las siguientes condiciones:

  • El formulario vence el 16 de junio de 2020 a las 11:11:11 UTC.
  • El nombre del archivo puede comenzar con cualquier carácter válido.
  • El archivo debe subirse al depósito travel-maps.
  • Si la carga se realiza de forma correcta, se redirecciona al usuario a http://www.example.com/success_notification.html.
  • El formulario solo permite subir imágenes.
  • Un usuario no puede subir un archivo de más de 1 MB.

Alcance de la credencial

El alcance de la credencial es una string que aparece en las string para firmar y en los documentos de políticas. El alcance de la credencial tiene la siguiente estructura:

DATE/LOCATION/SERVICE/REQUEST_TYPE

El permiso de la credencial tiene los siguientes componentes:

  • DATE: La fecha en la que se puede usar la firma, con el formato AAAAMMDD
  • LOCATION: En los recursos de Cloud Storage, puedes usar cualquier valor de LOCATION. El valor que se recomienda usar es la ubicación asociada con el recurso al que se aplica la firma. Por ejemplo, us-central1. Este parámetro existe para mantener la compatibilidad con Amazon S3.
  • SERVICE: el nombre del servicio En la mayoría de los casos, cuando accedes a los recursos de Cloud Storage, este valor es storage. Cuando usas extensiones x-amz de Amazon S3, este valor es s3.
  • REQUEST_TYPE: El tipo de solicitud. En la mayoría de los casos, cuando accedes a los recursos de Cloud Storage, este valor es goog4_request. Cuando usas extensiones x-amz de Amazon S3, este valor es aws4_request.

Por ejemplo, a continuación, se muestra un típico alcance de la credencial:

20191102/us-central1/storage/goog4_request

Por otro lado, cuando se usa una string para firmar con extensiones x-amz, el alcance de la credencial se ve de la siguiente manera:

20150830/us-east1/s3/aws4_request

Firma

Para crear una firma, debes usar un algoritmo de firma, también conocido como función de hash criptográfica, a fin de firmar tu string para firmar o documento de políticas. El algoritmo de firma que debes uses depende del tipo de clave de autenticación que tengas:

Clave de autenticación Algoritmo de firma Clave de firma
Clave RSA RSA-SHA256 Usa directamente la clave privada RSA
Clave HMAC HMAC-SHA256 Deriva a partir del secreto de la clave HMAC

Consulta Crea firmas a fin de obtener una guía para firmar tu cadena para firmar o documento de políticas mediante una clave RSA y el método signBlob de IAM.

Deriva la clave de firma de la clave HMAC

Cuando firmas con una clave HMAC, debes crear una clave de firma codificada en UTF-8 que se derive de la clave secreta HMAC. La clave derivada es específica para la fecha, la ubicación, el servicio y el tipo de solicitud asociados con tu solicitud. En el siguiente seudocódigo, se muestra cómo derivar la clave de firma:

key_date = HMAC-SHA256("PREFIX" + HMAC_KEY_SECRET, "DATE")
key_region = HMAC-SHA256(key_date, "LOCATION")
key_service = HMAC-SHA256(key_region, "SERVICE")
signing_key = HMAC-SHA256(key_service, "REQUEST_TYPE")

El seudocódigo tiene los siguientes componentes:

  • PREFIX: En la mayoría de los casos, cuando accedes a los recursos de Cloud Storage, este valor es GOOG4. Cuando usas extensiones x-amz de Amazon S3, este valor es AWS4.
  • HMAC_KEY_SECRET: El secreto de la clave HMAC que usas para realizar y firmar la solicitud.
  • DATE, LOCATION, SERVICE y REQUEST_TYPE: Estos valores deben coincidir con los valores especificados en el alcance de la credencial.

Después de la firma

Para completar la firma, el resultado, llamado resumen del mensaje, debe estar codificado en hexadecimal.

Ejemplo

A continuación, se muestra un seudocódigo que se usa a fin de firmar un documento de políticas:

EncodedPolicy = Base64Encode(PolicyDocument)
MessageDigest = SigningAlgorithm(SigningKey, EncodedPolicy)
Signature = HexEncode(MessageDigest)

A continuación, se muestra un seudocódigo que se usa a fin de firmar una string para firmar:

MessageDigest = SigningAlgorithm(SigningKey, StringToSign)
Signature = HexEncode(MessageDigest)

Limitaciones

Las firmas no se pueden usar para autenticar una carga si esta usa codificación de transferencia fragmentada. Usa los tokens de OAuth 2.0 si deseas usar la codificación de transferencia fragmentada en tus cargas.

¿Qué sigue?