Firmas

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

Las firmas son específicas de la API XML de Cloud Storage y son distintas de los tokens de OAuth 2.0. Los tokens de OAuth 2.0 también se pueden usar con la API XML y se aplican de forma más general a los servicios de Google Cloud , incluida la API JSON de Cloud Storage.

Información general

Las firmas proporcionan tanto identidad como autenticación sólida, lo que asegura que las solicitudes a Cloud Storage se procesen con la autoridad de una cuenta específica. Las firmas consiguen esta autenticación sin revelar la información sensible de la clave, denominada secretos o claves privadas, asociada a esa cuenta.

Cuando haces una solicitud con una firma, Cloud Storage usa su copia de la información de la clave para calcular una firma equivalente para la solicitud. Si la firma incluida en la solicitud coincide con la firma calculada por Cloud Storage, Cloud Storage sabrá que la firma se ha creado con la clave secreta o privada correspondiente.

En Cloud Storage, las firmas deben usarse al trabajar con lo siguiente:

Además, las firmas se pueden usar en el encabezado Authorization de las solicitudes de la API XML.

Usar firmas en solicitudes directas es útil cuando se realizan migraciones sencillas 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 vayas a dar y de la clave de autenticación con la que estés trabajando. En general, una firma tiene dos componentes: la clave de firma y la información de la solicitud. Para crear la firma, se aplica un algoritmo de firma a estos dos componentes. En la siguiente tabla se resumen los diferentes casos prácticos de las firmas y los componentes que necesitas en cada caso para crear la firma:

Caso práctico Clave de firma Solicitar información
Formulario HTML con una clave RSA Usar directamente la clave privada RSA Documento de política codificado en Base64
Formulario HTML con una clave HMAC Derivar del secreto de la clave HMAC Documento de política codificado en Base64
URL o encabezado firmado con una clave RSA Usar directamente la clave privada RSA Cadena que se va a firmar
URL firmada o encabezado firmado con una clave HMAC Derivar del secreto de la clave HMAC Cadena que se va a firmar

Cadena que se va a firmar

Una cadena que se va a firmar incluye metainformación sobre tu solicitud y un hash de la solicitud canónica que quieres firmar.

Estructura

Una cadena que se va a firmar debe estar codificada en UTF-8 y tener la siguiente estructura, con saltos de línea entre cada elemento:

SIGNING_ALGORITHM
ACTIVE_DATETIME
CREDENTIAL_SCOPE
HASHED_CANONICAL_REQUEST

Algoritmo de firma

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

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

Fecha y hora de activación

Fecha y hora en las que se puede usar la firma, en formato básico ISO 8601 YYYYMMDD'T'HHMMSS'Z'.

  • En el caso de las URLs 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 cadena de consulta X-Goog-Date de la URL firmada y deben usar el mismo día que especifiques en el ámbito de la credencial.

  • En las solicitudes con encabezados firmados, la firma se puede usar desde 15 minutos antes de la fecha y hora activas hasta 15 minutos después de la fecha y hora activas. La fecha y hora activas deben coincidir con el encabezado x-goog-date de la solicitud mediante la firma, y deben corresponder al mismo día que especifiques en el ámbito de las credenciales.

Ámbito de la credencial

El ámbito de las credenciales de la solicitud.

Hash de la solicitud canónica

El hash SHA-256 codificado en hexadecimal de una solicitud canónica. Usa una función de cifrado con hash SHA-256 para crear un valor de hash de la solicitud canónica. Tu lenguaje de programación debe tener una biblioteca para crear hashes SHA-256. Un ejemplo de valor hash es el siguiente:

436b7ce722d03b17d3f790255dd57904f7ed61c02ac5127a0ca8063877e4e42c

Ejemplo

A continuación, se muestra un ejemplo de cadena con formato correcto para firmar, con saltos de línea reales y no \n:

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

Documento de la política

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

Los documentos de políticas se crean en formato JavaScript Object Notation (JSON). El documento de la política debe estar codificado en UTF-8 y en Base64. Un documento de política contiene las siguientes secciones:

Entrada Descripción
expiration Hora de vencimiento del documento de política en formato básico ISO 8601 YYYYMMDD'T'HHMMSS'Z'. Si el documento de política ha caducado, el formulario HTML dejará de funcionar.
conditions Un conjunto de condiciones que todas las subidas deben cumplir.

La sección conditions debe incluir lo siguiente:

  • Una instrucción condicional para cada campo que utilice en su formulario HTML, excepto para los campos x-goog-signature, file y policy.

  • Una instrucción de condición "bucket", aunque no uses el campo de segmento en tu formulario HTML.

Si quieres usar varias instrucciones de condición para el mismo campo, debes crear un formulario HTML independiente para cada una. Puede usar tres tipos de condiciones en sus instrucciones de condición:

  • Concordancia exacta

    Busca una coincidencia exacta de un campo. El valor utilizado en el campo especificado del formulario HTML debe coincidir con el valor definido en esta condición. Defina esta condición con uno de los siguientes estilos de sintaxis:

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

    Todos los campos de formulario HTML válidos, excepto Content-Length, pueden usar la concordancia exacta.

  • Empieza por

    Si el valor de un campo debe empezar por 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, utilice 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.

  • Intervalo de duración del contenido

    Especifica un intervalo 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ítica:

{"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"}
  ]
}

En este documento de la política se definen las siguientes condiciones:

  • El formulario caduca el 16 de junio del 2020 a las 11:11:11 (UTC).
  • El nombre del archivo puede empezar por cualquier carácter válido.
  • El archivo debe subirse al contenedor travel-maps.
  • Si la subida se realiza correctamente, se redirige al usuario a http://www.example.com/success_notification.html.
  • El formulario solo permite descargar imágenes.
  • Los usuarios no pueden subir un archivo de tamaño superior a 1 MB.

Ámbito de las credenciales

El ámbito de las credenciales es una cadena que aparece tanto en las cadenas que se van a firmar como en los documentos de políticas. El ámbito de la credencial tiene la siguiente estructura:

DATE/LOCATION/SERVICE/REQUEST_TYPE

El ámbito de las credenciales tiene los siguientes componentes:

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

Por ejemplo, un ámbito de credenciales típico tiene el siguiente aspecto:

20191102/us-central1/storage/goog4_request

El ámbito de las credenciales al usar una cadena para firmar con extensiones de x-amz es el siguiente:

20150830/us-east1/s3/aws4_request

Firma

Para crear una firma, se usa un algoritmo de firma, también conocido como función de hash criptográfica, para firmar la cadena que se va a firmar o el documento de política. El algoritmo de firma genera un resumen del mensaje, que debe codificarse en hexadecimal para crear la firma final. El algoritmo de firma que utilices dependerá del tipo de clave de autenticación que tengas:

Clave de autenticación Algoritmo de firma Clave de firma
Clave RSA RSA-SHA256 Usar directamente la clave privada RSA
Clave HMAC HMAC-SHA256 Derivar del secreto de la clave HMAC

El algoritmo de firma RSA-SHA256 se puede ejecutar con el método signBlob de IAM. Herramientas como la CLI de gcloud y la mayoría de las Google Cloud bibliotecas de cliente te permiten crear URLs firmadas con el método signBlob.

También puedes crear firmas de claves RSA de forma local con un lenguaje de programación que tenga una biblioteca para realizar firmas RSA, como la biblioteca pyopenssl. Sin embargo, no se recomienda este método, ya que requiere que crees y descargues la clave privada de una cuenta de servicio.

Derivar 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 del secreto de tu clave HMAC. La clave derivada es específica de la fecha, la ubicación, el servicio y el tipo de solicitud asociados a tu solicitud. En el siguiente pseudocó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 pseudocódigo tiene los siguientes componentes:

  • PREFIX: en la mayoría de los casos, cuando se accede a recursos de Cloud Storage, este valor es GOOG4. Cuando se usan extensiones de Amazon S3 x-amz, este valor es AWS4.
  • HMAC_KEY_SECRET: el secreto de la clave HMAC que usas para crear y firmar la solicitud.
  • DATE, LOCATION, SERVICE y REQUEST_TYPE: estos valores deben coincidir con los especificados en el ámbito de las credenciales.

Una vez que hayas derivado la clave de firma, crea la firma localmente con un lenguaje de programación que incluya una biblioteca con el algoritmo de firma HMAC-SHA256.

Después de firmar

Para completar la firma, la salida de la firma, denominada resumen del mensaje, debe codificarse en hexadecimal.

Ejemplo

A continuación, se muestra el pseudocódigo para firmar un documento de política:

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

A continuación se muestra el pseudocódigo para firmar una cadena:

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

Siguientes pasos