Cálculos de assinatura para o cabeçalho de autorização: transferência de carga útil em uma única parte (AWS Signature Version 4)
Ao usar o cabeçalho Authorization para autenticar solicitações, o valor do cabeçalho inclui, entre outras coisas, uma assinatura. Os cálculos da assinatura variam de acordo com a escolha de transferência da carga útil (Visão geral). Esta seção explica cálculos de assinatura quando você decide transferir a carga útil em uma única parte. A seção de exemplo (consulte Exemplos: cálculos de assinatura) mostra cálculos de assinatura e cabeçalhos Authorization resultantes que você pode usar como um conjunto de testes para verificar seu código.
Importante
Ao transferir a carga útil em uma única parte, você pode optar por incluir o hash da carga útil nos cálculos da assinatura, chamado de carga útil assinada (se você não a incluir, a carga útil será considerada não assinada). O procedimento de assinatura discutido na seção a seguir se aplica a ambos, mas observe as seguintes diferenças:
-
Opção de carga útil assinada: você inclui o hash da carga útil ao criar a solicitação canônica (que então se torna parte de StringToSign, conforme explicado na seção de cálculo da assinatura). Você também especifica o mesmo valor como o valor do cabeçalho
x-amz-content-sha256ao enviar a solicitação para o S3. -
Opção de carga útil não assinada: inclua a string literal
UNSIGNED-PAYLOADao construir uma solicitação canônica e defina o mesmo valor como o cabeçalhox-amz-content-sha256ao enviar a solicitação para o Amazon S3.
Quando você envia a solicitação para o Amazon S3, o valor do cabeçalho x-amz-content-sha256 informa ao Amazon S3 se a carga útil está assinada ou não. O Amazon S3 pode então criar a assinatura adequadamente para verificação.
Em ambos os casos, como o valor do cabeçalho x-amz-content-sha256 já faz parte da HashedPayload, você não precisa incluir o cabeçalho x-amz-content-sha256 como cabeçalho canônico.
Cálculo de uma assinatura
Para calcular uma assinatura, primeiro é necessário usar uma string para assinar. Em seguida, calcule um hash HMAC-SHA256 da string a ser assinada usando uma chave de assinatura. O diagrama a seguir ilustra o processo, incluindo os vários componentes da string criada para assinatura
Ao receber uma solicitação autenticada, o Amazon S3 calcula a assinatura e a compara com a assinatura que você forneceu na solicitação. Por esse motivo, é necessário calcular a assinatura usando o mesmo método usado pelo Amazon S3. O processo de colocar uma solicitação em um formulário estabelecido para assinatura se chama canonização.
A tabela a seguir descreve as funções exibidas no diagrama. É necessário implementar o código para essas funções.
| Função | Descrição |
|---|---|
Lowercase() |
Converta a string em letras minúsculas. |
Hex() |
Codificação de base 16 em letras minúsculas. |
SHA256Hash() |
Função de hash criptográfico do Secure Hash Algorithm (SHA). |
HMAC-SHA256() |
Calcula o HMAC usando o algoritmo SHA256 com a chave de assinatura fornecida. Essa é a assinatura final. |
Trim() |
Remova qualquer espaço em branco inicial e final. |
UriEncode() |
O URI codifica cada byte. O UriEncode() deve aplicar as seguintes regras:
ImportanteAs funções UriEncode padrão fornecidas por sua plataforma de desenvolvimento podem não funcionar devido às diferenças na implementação e à ambiguidade relacionada nos RFCs subjacentes. É recomendável escrever sua própria função UriEncode personalizada para garantir que a codificação funcione. Veja a seguir um exemplo da função UriEncode() em Java.
|
Tarefa 1: Criar uma solicitação canônica
Esta seção fornece uma visão geral da criação de uma solicitação canônica.
Confira a seguir o formato de solicitação canônica que o Amazon S3 usa para calcular uma assinatura. Para que as assinaturas coincidam, você deve criar uma solicitação canônica neste formato:
<HTTPMethod>\n<CanonicalURI>\n<CanonicalQueryString>\n<CanonicalHeaders>\n<SignedHeaders>\n<HashedPayload>
Em que:
-
HTTPMethodé um dos métodos HTTP, por exemplo, GET, PUT, HEAD e DELETE. -
CanonicalUrié a versão codificada por URI do componente de caminho absoluto do URI, começando pelo “/” após o nome do domínio e seguindo até o final da string ou até o caractere de ponto de interrogação (“?”), se houver parâmetros de string de consulta. O URI no seguinte exemplo,/examplebucket/myphoto.jpg, é o caminho absoluto, e você não codifica o “/” no caminho absoluto:http://s3.amazonaws.com/examplebucket/myphoto.jpgnota
Não normalize caminhos de URI para solicitações ao Amazon S3. Por exemplo, você pode ter um bucket com um objeto chamado "my-object//example//photo.user". A normalização do caminho altera o nome do objeto na solicitação para "my-object/example/photo.user". Esse é um caminho incorreto para esse objeto.
-
CanonicalQueryStringespecifica os parâmetros da string de consulta codificados por URI. Codifique por URI o nome e os valores individualmente. Também é necessário classificar os parâmetros na string de consulta canônica em ordem alfabética pelo nome da chave. A classificação ocorre após a codificação. A string de consulta no seguinte exemplo de URI éprefix=somePrefix&marker=someMarker&max-keys=20:http://s3.amazonaws.com/examplebucket?prefix=somePrefix&marker=someMarker&max-keys=20A string de consulta canônica é como este exemplo (quebras de linha foram adicionadas ao exemplo para facilitar a leitura):
UriEncode("marker")+"="+UriEncode("someMarker")+"&"+ UriEncode("max-keys")+"="+UriEncode("20") + "&" + UriEncode("prefix")+"="+UriEncode("somePrefix")Quando uma solicitação se destina a um sub-recurso, o valor do parâmetro de consulta correspondente é uma string vazia (“”). Por exemplo, o URI a seguir identifica o sub-recurso
ACLno bucketexamplebucket:http://s3.amazonaws.com/examplebucket?aclA CanonicalQueryString nesse caso é a seguinte:
UriEncode("acl") + "=" + ""Se o URI não contém um “?”, não há strings de consulta na solicitação, e você define a string de consulta canônica como uma string vazia (“”). Você ainda precisará incluir o “\n”.
-
CanonicalHeadersé uma lista de cabeçalhos de solicitação com os respectivos valores. Os pares individuais de nome e valor do cabeçalho são separados pelo caractere de nova linha (“\n”). Os nomes de cabeçalho devem estar em letras minúsculas. É necessário classificar esses nomes em ordem alfabética para criar a string, conforme mostrado no exemplo a seguir:Lowercase(<HeaderName1>)+":"+Trim(<value>)+"\n" Lowercase(<HeaderName2>)+":"+Trim(<value>)+"\n" ... Lowercase(<HeaderNameN>)+":"+Trim(<value>)+"\n"As funções
Lowercase()eTrim()usadas neste exemplo estão descritas na seção anterior.A lista
CanonicalHeadersdeve conter:-
Cabeçalho HTTP
host -
Se o cabeçalho
Content-MD5estiver presente na solicitação, você deverá adicioná-lo à listaCanonicalHeaders. -
Também deverão ser adicionados todos os cabeçalhos
x-amz-*que você pretende incluir na solicitação. Por exemplo, se você estiver usando credenciais de segurança temporárias, precisará incluir ox-amz-security-tokenna solicitação. É necessário adicionar esse cabeçalho à lista deCanonicalHeaders.
nota
O cabeçalho
x-amz-content-sha256é obrigatório para todas as solicitações do AWS Signature Version 4. Ele fornece um hash da carga da solicitação. No entanto, você não precisa incluir ox-amz-content-sha256como cabeçalho canônico porque o S3 usará automaticamente seu valor ao calcular o hash de carga útil enviado na solicitação.Se não houver carga útil, será necessário fornecer o hash de uma string vazia.
Se você não quiser que o S3 verifique o hash da solicitação, use a string literal
"UNSIGNED-PAYLOAD".
Veja a seguir um exemplo de strings
CanonicalHeaders. O nomes dos cabeçalhos estão em letras minúsculas e são classificados.exemplo Exemplo 1
host:s3.amazonaws.com x-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 x-amz-date:20130708T220855Zexemplo Exemplo 2
host:s3.amazonaws.com x-amz-content-sha256:UNSIGNED-PAYLOAD x-amz-date:20130708T220855Zexemplo Exemplo 3
host:s3.amazonaws.com x-amz-date:20130708T220855Znota
Para fins de cálculo de uma assinatura de autorização, o cabeçalho do host e todos os cabeçalhos
x-amz-*, excetox-amz-content-sha256, são necessários. No entanto, para evitar a adulteração de dados, convém incluir todos os cabeçalhos no cálculo da assinatura.Assinar o cabeçalho
x-amz-content-sha256é opcional porque o S3 usará seu valor ao calcular o hash da carga útil da solicitação recebida. -
-
SignedHeadersé uma lista em ordem alfabética, separada por ponto e vírgula, de nomes de cabeçalhos de solicitação em letras minúsculas. Os cabeçalhos de solicitação da lista são os mesmos cabeçalhos que você incluiu na stringCanonicalHeaders. Nos exemplos anteriores, o valor deSignedHeadersseria:exemplo Exemplos 1 e 2
host;x-amz-content-sha256;x-amz-dateexemplo Exemplo 3
host;x-amz-date -
HashedPayloadé o valor hexadecimal do hash SHA256 da carga útil da solicitação.Hex(SHA256Hash(<payload>)Se não houver carga útil na solicitação, calcule um hash da string vazia da seguinte forma:
Hex(SHA256Hash(""))O hash retorna o seguinte valor:
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855Por exemplo, ao carregar um objeto usando uma solicitação PUT, forneça dados do objeto no corpo. Ao recuperar um objeto usando uma solicitação GET, calcule o hash da string vazia.
Tarefa 2: Criar uma string para assinar
Esta seção fornece uma visão geral da criação de uma string a ser assinada. Para obter instruções passo a passo, consulte Tarefa 2: criar uma string a ser assinada na Referência geral da AWS.
A string a ser assinada é uma concatenação destas strings:
"AWS4-HMAC-SHA256" + "\n" + timeStampISO8601Format + "\n" +<Scope>+ "\n" + Hex(SHA256Hash(<CanonicalRequest>))
A string constante AWS4-HMAC-SHA256 especifica o algoritmo de hash que você está usando, HMAC-SHA256. timeStamp é a hora UTC atual no formato ISO 8601 (por exemplo, 20130524T000000Z).
Scope vincula a assinatura resultante a uma data específica, uma Região da AWS e um serviço. Assim, sua assinatura resultante funcionará somente na região específica e para um serviço específico. A assinatura é válida por sete dias após a data especificada.
date.Format(<YYYYMMDD>) + "/" +<region>+ "/" +<service>+ "/aws4_request"
Para o Amazon S3, a string de serviço é s3. Para obter uma lista de strings de região, consulte Regiões e endpoints na Referência geral da AWS. A coluna Região nesta tabela fornece a lista de strings de região válidas.
O escopo a seguir restringe a assinatura resultante à região us-east-1 e ao Amazon S3.
20130606/us-east-1/s3/aws4_request
nota
Scope deve usar a mesma data que você usa para calcular a chave de assinatura, conforme discutido na seção a seguir.
Tarefa 3: calcular a assinatura
No AWS Signature Version 4, em vez de usar suas chaves de acesso da AWS para assinar uma solicitação, primeiro crie uma chave de assinatura que tenha como escopo uma região e um serviço específicos. Para obter mais informações sobre chaves de assinatura, consulte Introdução à assinatura de solicitações.
DateKey = HMAC-SHA256("AWS4"+"<SecretAccessKey>", "<YYYYMMDD>") DateRegionKey = HMAC-SHA256(<DateKey>, "<aws-region>") DateRegionServiceKey = HMAC-SHA256(<DateRegionKey>, "<aws-service>") SigningKey = HMAC-SHA256(<DateRegionServiceKey>, "aws4_request")
nota
Alguns casos de uso podem processar chaves de assinatura por até sete dias. Para obter mais informações, consulte Compartilhar um objeto com outras pessoas.
Para obter uma lista de strings de região, consulte Regiões e endpoints na Referência geral da AWS.
O uso de uma chave de assinatura permite que você mantenha suas credenciais da AWS em um local seguro. Por exemplo, se você tiver vários servidores que se comunicam com o Amazon S3, compartilhe a chave de assinatura com esses servidores; você não precisa manter uma cópia da sua chave de acesso secreta em cada servidor. A chave de assinatura é válida por até sete dias. Portanto, toda vez que você calcular a chave de assinatura, precisará compartilhá-la com os servidores. Para obter mais informações, consulte Autenticação de solicitações (AWS Signature Version 4).
A assinatura final é o hash HMAC-SHA256 da string a ser assinada, usando a chave de assinatura como chave.
HMAC-SHA256(SigningKey, StringToSign)
Para obter instruções passo a passo sobre como criar uma assinatura, consulte Tarefa 3: criar uma assinatura na Referência geral da AWS.
Exemplos: cálculos de assinatura
Você pode usar os exemplos desta seção como uma referência para verificar os cálculos de assinatura no seu código. Os cálculos mostrados nos exemplos usam os seguintes dados:
-
Exemplo de chaves de acesso.
Parâmetro Valor AWSAccessKeyIdAKIAIOSFODNN7EXAMPLEAWSSecretAccessKeywJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY -
Solicite o carimbo de data/hora de 20130524T000000Z (
Fri, 24 May 2013 00:00:00 GMT). -
Nome do bucket:
examplebucket. -
Presume-se que o bucket esteja na região Leste dos EUA (Norte da Virgínia). A credencial
Scopee os cálculos deSigning Keyusamus-east-1como especificador de região. Para obter informações sobre outras regiões, consulte Regiões e endpoints na Referência geral da AWS. -
Você pode usar solicitações no estilo de caminho ou no estilo hospedado virtual. Os exemplos a seguir mostram como assinar uma solicitação no estilo hospedado virtual, por exemplo:
https://examplebucket.s3.amazonaws.com/photos/photo1.jpgPara obter mais informações, consulte Hospedagem virtual de buckets no Guia do usuário do Amazon Simple Storage Service.
Exemplo: objeto GET
O exemplo a seguir obtém os primeiros 10 bytes de um objeto (test.txt) de examplebucket. Para obter mais informações sobre a ação da API, consulte GetObject.
GET /test.txt HTTP/1.1 Host: examplebucket.s3.amazonaws.com Authorization:SignatureToBeCalculatedRange: bytes=0-9 x-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 x-amz-date: 20130524T000000Z
Como essa solicitação GET não fornece nenhum conteúdo no corpo, o valor x-amz-content-sha256 pode ser o hash do corpo vazio da solicitação ou a string literal "UNSIGNED-PAYLOAD". As etapas a seguir mostram os cálculos de assinatura e a construção do cabeçalho Authorization usando o hash de uma string vazia.
-
StringToSign
-
CanonicalRequest
GET /test.txt host:examplebucket.s3.amazonaws.com range:bytes=0-9 x-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 x-amz-date:20130524T000000Z host;range;x-amz-content-sha256;x-amz-date e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855Na string de solicitação canônica, a última linha é o hash do corpo da solicitação vazio. A terceira linha está vazia porque não há parâmetros de consulta na solicitação.
-
StringToSign
AWS4-HMAC-SHA256 20130524T000000Z 20130524/us-east-1/s3/aws4_request 7344ae5b7ee6c3e7e6b0fe0640412a37625d1fbfff95c48bbb2dc43964946972
-
-
SigningKey
signing key = HMAC-SHA256(HMAC-SHA256(HMAC-SHA256(HMAC-SHA256("AWS4" + "<YourSecretAccessKey>","20130524"),"us-east-1"),"s3"),"aws4_request") -
Signature
f0e8bdb87c964420e857bd35b5d6ed310bd44f0170aba48dd91039c6036bdb41 -
Cabeçalho de autorização
O cabeçalho
Authorizationresultante é o seguinte:AWS4-HMAC-SHA256 Credential=AKIAIOSFODNN7EXAMPLE/20130524/us-east-1/s3/aws4_request,SignedHeaders=host;range;x-amz-content-sha256;x-amz-date,Signature=f0e8bdb87c964420e857bd35b5d6ed310bd44f0170aba48dd91039c6036bdb41
Exemplo: objeto PUT
Este exemplo de solicitação PUT cria um objeto (test$file.text) em examplebucket. O exemplo supõe o seguinte:
-
Você está solicitando
REDUCED_REDUNDANCYcomo classe de armazenamento adicionando o cabeçalho de solicitaçãox-amz-storage-class. Para obter informações sobre classes de armazenamento, consulte Classes de armazenamento no Guia do usuário do Amazon Simple Storage Service. -
O conteúdo do arquivo enviado é uma string,
"Welcome to Amazon S3."O valor dex-amz-content-sha256na solicitação é baseado nessa string.
Para obter informações sobre a ação da API, consulte PutObject.
PUT test$file.text HTTP/1.1 Host: examplebucket.s3.amazonaws.com Date: Fri, 24 May 2013 00:00:00 GMT Authorization:SignatureToBeCalculatedx-amz-date: 20130524T000000Z x-amz-storage-class: REDUCED_REDUNDANCY x-amz-content-sha256: 44ce7dd67c959e0d3524ffac1771dfbba87d2b6b4b4e99e42034a8b803f8b072<Payload>
As etapas a seguir mostram cálculos de assinatura.
-
StringToSign
-
CanonicalRequest
PUT /test%24file.text date:Fri, 24 May 2013 00:00:00 GMT host:examplebucket.s3.amazonaws.com x-amz-content-sha256:44ce7dd67c959e0d3524ffac1771dfbba87d2b6b4b4e99e42034a8b803f8b072 x-amz-date:20130524T000000Z x-amz-storage-class:REDUCED_REDUNDANCY date;host;x-amz-content-sha256;x-amz-date;x-amz-storage-class 44ce7dd67c959e0d3524ffac1771dfbba87d2b6b4b4e99e42034a8b803f8b072Na solicitação canônica, a terceira linha está vazia, pois não há parâmetros de consulta na solicitação. O cabeçalho canônico
x-amz-content-sha256pode ser assinado opcionalmente, pois o hash de carga útil já é fornecido na parte inferior da solicitação. A última linha é o hash do corpo, que deve ser igual ao valorx-amz-content-sha256 headerenviado ao S3 na solicitação HTTP. -
StringToSign
AWS4-HMAC-SHA256 20130524T000000Z 20130524/us-east-1/s3/aws4_request 9e0e90d9c76de8fa5b200d8c849cd5b8dc7a3be3951ddb7f6a76b4158342019d
-
-
SigningKey
signing key = HMAC-SHA256(HMAC-SHA256(HMAC-SHA256(HMAC-SHA256("AWS4" + "<YourSecretAccessKey>","20130524"),"us-east-1"),"s3"),"aws4_request") -
Signature
98ad721746da40c64f1a55b78f14c238d841ea1380cd77a1b5971af0ece108bd -
Cabeçalho de autorização
O cabeçalho
Authorizationresultante é o seguinte:AWS4-HMAC-SHA256 Credential=AKIAIOSFODNN7EXAMPLE/20130524/us-east-1/s3/aws4_request,SignedHeaders=date;host;x-amz-content-sha256;x-amz-date;x-amz-storage-class,Signature=98ad721746da40c64f1a55b78f14c238d841ea1380cd77a1b5971af0ece108bd
Exemplo: ciclo de vida do bucket GET
A solicitação GET a seguir recupera a configuração de ciclo de vida de examplebucket. Para obter informações sobre a ação da API, consulte GetBucketLifecycleConfiguration.
GET ?lifecycle HTTP/1.1 Host: examplebucket.s3.amazonaws.com Authorization:SignatureToBeCalculatedx-amz-date: 20130524T000000Z x-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
Como a solicitação não fornece nenhum conteúdo no corpo, o valor do cabeçalho x-amz-content-sha256 é o hash do corpo vazio da solicitação. As etapas a seguir mostram cálculos de assinatura.
-
StringToSign
-
CanonicalRequest
GET / lifecycle= host:examplebucket.s3.amazonaws.com x-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 x-amz-date:20130524T000000Z host;x-amz-content-sha256;x-amz-date e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855Na solicitação canônica, a última linha é o hash do corpo da solicitação vazio.
-
StringToSign
AWS4-HMAC-SHA256 20130524T000000Z 20130524/us-east-1/s3/aws4_request 9766c798316ff2757b517bc739a67f6213b4ab36dd5da2f94eaebf79c77395ca
-
-
SigningKey
signing key = HMAC-SHA256(HMAC-SHA256(HMAC-SHA256(HMAC-SHA256("AWS4" + "<YourSecretAccessKey>","20130524"),"us-east-1"),"s3"),"aws4_request") -
Signature
fea454ca298b7da1c68078a5d1bdbfbbe0d65c699e0f91ac7a200a0136783543 -
Cabeçalho de autorização
O cabeçalho
Authorizationresultante é o seguinte:AWS4-HMAC-SHA256 Credential=AKIAIOSFODNN7EXAMPLE/20130524/us-east-1/s3/aws4_request,SignedHeaders=host;x-amz-content-sha256;x-amz-date,Signature=fea454ca298b7da1c68078a5d1bdbfbbe0d65c699e0f91ac7a200a0136783543
Exemplo: obter bucket (listar objetos)
O exemplo a seguir recupera uma lista de objetos do bucket examplebucket. Para obter informações sobre a ação da API, consulte ListObjects.
GET ?max-keys=2&prefix=J HTTP/1.1 Host: examplebucket.s3.amazonaws.com Authorization:SignatureToBeCalculatedx-amz-date: 20130524T000000Z x-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
Como a solicitação não fornece um corpo, o valor de x-amz-content-sha256 é o hash do corpo da solicitação vazio. As etapas a seguir mostram cálculos de assinatura.
-
StringToSign
-
CanonicalRequest
GET / max-keys=2&prefix=J host:examplebucket.s3.amazonaws.com x-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 x-amz-date:20130524T000000Z host;x-amz-content-sha256;x-amz-date e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855Na string canônica, a última linha é o hash do corpo da solicitação vazio.
-
StringToSign
AWS4-HMAC-SHA256 20130524T000000Z 20130524/us-east-1/s3/aws4_request df57d21db20da04d7fa30298dd4488ba3a2b47ca3a489c74750e0f1e7df1b9b7
-
-
SigningKey
signing key = HMAC-SHA256(HMAC-SHA256(HMAC-SHA256(HMAC-SHA256("AWS4" + "<YourSecretAccessKey>","20130524"),"us-east-1"),"s3"),"aws4_request") -
Signature
34b48302e7b5fa45bde8084f4b7868a86f0a534bc59db6670ed5711ef69dc6f7 -
Cabeçalho de autorização
O cabeçalho
Authorizationresultante é o seguinte:AWS4-HMAC-SHA256 Credential=AKIAIOSFODNN7EXAMPLE/20130524/us-east-1/s3/aws4_request,SignedHeaders=host;x-amz-content-sha256;x-amz-date,Signature=34b48302e7b5fa45bde8084f4b7868a86f0a534bc59db6670ed5711ef69dc6f7