Assinaturas

As assinaturas são um método para autenticar as solicitações enviadas para a API XML do Cloud Storage. As assinaturas são usadas, por exemplo, ao trabalhar com URLs assinados ou formulários HTML.

Visão geral

As assinaturas fornecem identidade e autenticação forte, o que garante que as solicitações para o Cloud Storage sejam processadas usando a autoridade de uma conta específica. As assinaturas recebem essa autenticação sem revelar as informações confidenciais da chave, chamadas de secrets, associadas a esta conta.

Ao fazer uma solicitação com uma assinatura, o Cloud Storage usa a cópia do secret para calcular uma assinatura equivalente para a solicitação. Se a assinatura incluída na solicitação corresponder à assinatura calculada pelo Cloud Storage, o Cloud Storage saberá que a assinatura foi criada usando o secret relevante.

No Cloud Storage, as assinaturas precisam ser usadas ao trabalhar com:

Além disso, as assinaturas podem ser usadas ao fazer:

  • Solicitações assinadas diretamente para a API XML.

O uso de assinaturas em solicitações diretas é útil ao realizar migrações simples do Amazon S3. No entanto, o fluxo de autenticação recomendado para solicitações diretas é usar tokens OAuth 2.0.

Estrutura

Os componentes e o processo de criação de uma assinatura dependem de como ela será usada e da chave de autenticação com que você está trabalhando. No geral, há dois componentes em uma assinatura: a chave de assinatura e as informações de solicitação. Aplique um algoritmo de assinatura a ambos os componentes para criar a assinatura. A tabela abaixo resume os diferentes casos de uso para assinaturas e os componentes necessários em cada caso para criar a assinatura:

Caso de uso Chave de assinatura Informações de solicitação
Formulário HTML com uma chave RSA Usar diretamente o secret da chave RSA Documento de política codificado em Base64
Formulário HTML com uma chave HMAC Derivada do secret da chave HMAC Documento de política codificado em Base64
URL assinado ou solicitação assinada com uma chave RSA Usar diretamente o secret da chave RSA String a ser assinada
URL assinado ou solicitação assinada com uma chave HMAC Derivada do secret da chave HMAC String a ser assinada

String a ser assinada

Uma string a ser assinada inclui metainformações sobre sua solicitação e um hash da solicitação canônica que você quer assinar.

Estrutura

Uma string a ser assinada precisa ser codificada em UTF-8 e ter a seguinte estrutura, incluindo o uso de novas linhas entre cada elemento:

SIGNING_ALGORITHM
ACTIVE_DATETIME
CREDENTIAL_SCOPE
HASHED_CANONICAL_REQUEST

Algoritmo de assinatura

O valor usado para SIGNING_ALGORITHM depende do tipo de chave e das extensões usadas nos cabeçalhos ou em parâmetros de consulta:

Caso de uso Valor para SIGNING_ALGORITHM
Extensões x-goog-* e uma chave RSA GOOG4-RSA-SHA256
Extensões x-goog-* e uma chave HMAC GOOG4-HMAC-SHA256
Extensões x-amz-* e uma chave HMAC AWS4-HMAC-SHA256

Datetime ativa

A data e a hora em que a assinatura pode ser usada, no formato básico ISO 8601 (em inglês) YYYYMMDD'T'HHMMSS'Z'.

  • Para URLs assinados, a assinatura pode ser usada de 15 minutos antes da data e hora ativa até o prazo de validade especificado. A data/hora ativa precisa corresponder ao parâmetro de string de consulta X-Goog-Date do URL assinado e usar o mesmo dia especificado no escopo da credencial.

  • Para solicitações assinadas, a assinatura pode ser usada de 15 minutos antes da data/hora ativa até 15 minutos após a data/hora ativa. A data/hora ativa precisa corresponder ao cabeçalho de solicitação x-goog-date da solicitação assinada e usar o mesmo dia especificado no escopo da credencial.

Escopo da credencial

O escopo da credencial para a solicitação.

Hash da solicitação canônica

O hash SHA-256 codificado em hexadecimal de uma solicitação canônica. Use uma função de hash SHA-256 para criar um valor de hash da solicitação canônica. Sua linguagem de programação precisa ter uma biblioteca para criar hashes SHA-256. Veja abaixo um exemplo de valor de hash:

436b7ce722d03b17d3f790255dd57904f7ed61c02ac5127a0ca8063877e4e42c

Exemplo

Veja a seguir um exemplo de string a ser assinada devidamente formada, com novas linhas exibidas como novas linhas reais e não \n:

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

Documento de política

Um documento de política define quais usuários com acesso ao formulário HTML correspondente podem fazer upload para o Cloud Storage. Um documento de política fornece autorização para garantir que o formulário HTML possa fazer upload de arquivos para o bucket de destino. Você pode usar documentos de política para permitir que os visitantes de um site façam upload de arquivos para o Cloud Storage.

Um documento de política é construído em JSON (JavaScript Object Notation). O documento de política precisa ser codificado em UTF-8 e Base64. Um documento de política contém as seguintes seções:

Entrada Descrição
expiration O prazo de validade do documento de política, no formato básico ISO 8601 YYYYMMDD'T'HHMMSS'Z'. Um documento de política expirado causa a quebra do formulário HTML.
conditions Um conjunto de condições às quais todo upload precisa atender.

A seção conditions deve incluir:

  • Uma instrução de condição para cada campo usado no formulário HTML, exceto nos campos x-goog-signature, file e policy.

  • Uma instrução de condição "bucket", mesmo que o campo do bucket não seja usado no formulário HTML.

Se quiser usar várias instruções de condição para o mesmo campo, crie um formulário HTML separado para cada uma delas. Três tipos de condições podem ser usados em suas instruções de condição:

  • Correspondência exata

    Executa a correspondência exata para um campo. O valor usado no campo especificado do formulário HTML deve corresponder ao valor definido nesta condição. Defina esta condição usando um dos seguintes estilos de sintaxe:

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

    Todos os campos de formulário HTML válidos, exceto Content-Length, podem usar a correspondência exata.

  • Começa com

    Se o valor de um campo precisar começar com um determinado prefixo, use a condição starts-with com a seguinte sintaxe:

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

    Se o valor de um campo não tiver restrições, use a condição starts-with com a seguinte sintaxe:

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

    Todos os campos de formulário HTML válidos, exceto Content-Length, podem usar a condição starts-with.

  • Content Length Range

    Especifica um intervalo de valores aceitáveis que podem ser usados no campo Content-Length. Especifique esta condição usando a seguinte sintaxe:

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

Exemplo

Veja a seguir um exemplo de 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/auto/storage/goog4_request"},
  {"x-goog-date": "20191102T043530Z"}
  ]
}

Este documento de política define as seguintes condições:

  • O formulário expira em 16 de junho de 2020 às 11:11:11 UTC.
  • O nome do arquivo pode começar com qualquer caractere válido.
  • É necessário que seja feito upload do arquivo no bucket travel-maps.
  • Se o upload for bem-sucedido, o usuário será redirecionado para http://www.example.com/success_notification.html.
  • O formulário permite o envio apenas de imagens.
  • Um usuário não pode fazer upload de um arquivo maior que 1 MB.

Escopo da credencial

O escopo da credencial é uma string que aparece nos documentos de string a ser assinada e de política. O escopo da credencial tem a seguinte estrutura:

DATE/LOCATION/SERVICE/REQUEST_TYPE

O escopo da credencial tem os seguintes componentes:

  • DATE: a data em que a assinatura se torna utilizável, formatada como AAAAMMDD.
  • LOCATION: para recursos do Cloud Storage, use qualquer valor para LOCATION. O valor recomendado é auto. Este parâmetro existe para manter a compatibilidade com o Amazon S3.
  • SERVICE: o nome do serviço. Na maioria dos casos, ao acessar os recursos do Cloud Storage, esse valor é storage. Ao usar extensões x-amz do Amazon S3, este valor é s3.
  • REQUEST_TYPE: o tipo de solicitação. Na maioria dos casos, ao acessar os recursos do Cloud Storage, esse valor é goog4_request. Ao usar extensões x-amz do Amazon S3, este valor é aws4_request.

Por exemplo, um escopo de credencial típico tem esta aparência:

20191102/auto/storage/goog4_request

Enquanto que um escopo de credencial usando uma string a ser assinada com extensões x-amz tem esta aparência:

20150830/us-east-1/s3/aws4_request

Assinatura

Para criar uma assinatura, use um algoritmo de assinatura, também conhecido como função de hash criptográfico, para assinar seu documento de política ou string. O algoritmo de assinatura que você usa depende do tipo de chave de autenticação que você tem:

Chave de autenticação Algoritmo de assinatura Chave de assinatura
Chave RSA RSA-SHA256 Usar diretamente o secret da chave RSA
Chave HMAC HMAC-SHA256 Derivada do secret da chave HMAC

Derivar a chave de assinatura da chave HMAC

Ao assinar com uma chave HMAC, crie uma chave de assinatura codificada em UTF-8 derivada do secret da chave HMAC. A chave derivada é específica para a data, o local, o serviço e o tipo de solicitação associados à solicitação. No pseudocódigo a seguir, veja como derivar a chave de assinatura:

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

O pseudocódigo tem os seguintes componentes:

  • PREFIX: na maioria dos casos, ao acessar os recursos do Cloud Storage, esse valor é GOOG4. Ao usar extensões x-amz do Amazon S3, esse valor é AWS4.
  • HMAC_KEY_SECRET: o secret da chave HMAC que você está usando para fazer e assinar a solicitação.
  • DATE, LOCATION, SERVICE, REQUEST_TYPE: esses valores precisam corresponder aos valores especificados no escopo da credencial.

Após a assinatura

Para concluir a assinatura, o resultado da assinatura, chamado de resumo da mensagem, precisa ser codificado em hexadecimal.

Exemplo

Veja a seguir um pseudocódigo para assinar um documento de política:

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

Veja a seguir um pseudocódigo para assinar uma string a ser assinada:

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

A seguir