Cálculos de assinatura para o cabeçalho de autorização: transferência de carga útil em vários fragmentos (upload fragmentado) (AWS Signature Version 4)
Conforme descrito na Visão geral, ao autenticar solicitações usando o cabeçalho Authorization, você tem a opção de fazer upload da carga útil em fragmentos. Você pode enviar dados em fragmentos de tamanho fixo ou variável. Esta seção descreve o processo de cálculo da assinatura no upload fragmentado, como você cria o corpo do fragmento e como a assinatura atrasada funciona quando você faz upload do fragmento pela primeira vez e envia a assinatura no fragmento subsequente. A seção de exemplo (consulte Exemplo: objeto PUT) mostra cálculos de assinatura e cabeçalhos Authorization resultantes que você pode usar como um conjunto de testes para verificar seu código.
nota
Ao transferir dados em uma série de fragmentos, você deve fazer o seguinte:
-
Especifique explicitamente o tamanho total do conteúdo (tamanho do objeto em bytes mais metadados em cada parte) usando o cabeçalho HTTP
Content-Length. Para fazer isso, você deve pré-calcular o tamanho total da carga útil, incluindo os metadados enviados em cada parte, antes de iniciar sua solicitação. -
Especifique o cabeçalho HTTP
Transfer-Encoding. Se você incluir o cabeçalhoTransfer-Encodinge especificar qualquer valor diferente deidentity, deverá omitir o cabeçalhoContent-Length.
Para todas as solicitações, você deve incluir o cabeçalho x-amz-decoded-content-length, especificando o tamanho do objeto em bytes.
Cada cálculo de assinatura de fragmento inclui a assinatura do fragmento anterior. Para começar, você cria uma assinatura inicial usando somente os cabeçalhos. Você usa a assinatura inicial no cálculo da assinatura do primeiro fragmento. Para cada fragmento subsequente, você cria uma assinatura que inclui a assinatura do fragmento anterior. Assim, as assinaturas de fragmento são encadeadas; ou seja, a assinatura do fragmento n é uma função F(fragmento n, assinatura(fragmento n-1)). O encadeamento garante que você envie os fragmentos na ordem correta.
Para realizar um upload fragmentado, realize estas etapas:
-
Decida o tamanho do fragmento de carga útil. Você precisa disso ao gravar o código.
O tamanho do fragmento deve ser de pelo menos 8 KB. Recomendamos um tamanho de fragmento de pelo menos 64 KB para melhor desempenho. Esse tamanho de fragmento se aplica a todos os fragmentos, exceto o último. O último fragmento enviado pode ter menos de 8 KB. Se a carga útil for pequena e couber em um fragmento, ela poderá ser menor que 8 KB.
-
Crie a assinatura inicial para inclusão no primeiro fragmento. Para obter mais informações, consulte Cálculo da assinatura inicial.
-
Crie o primeiro fragmento e o transmita. Para obter mais informações, consulte Definição do corpo do fragmento.
-
Para cada fragmento subsequente, calcule a assinatura que inclui a assinatura anterior na string que você assina, construa o fragmento e o envie. Para obter mais informações, consulte Definição do corpo do fragmento.
-
Envie o fragmento adicional final, que é igual aos outros fragmentos na construção, mas tem zero bytes de dados. Para obter mais informações, consulte Definição do corpo do fragmento.
Cálculo da assinatura inicial
O diagrama a seguir ilustra o processo de cálculo da assinatura inicial.
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.
|
Para obter informações sobre o processo de assinatura, consulte Cálculos de assinatura para o cabeçalho de autorização: transferência de carga útil em uma única parte (AWS Signature Version 4). O processo é o mesmo, mas a criação de CanonicalRequest difere da seguinte forma:
-
Além dos cabeçalhos de solicitação que pretende adicionar, você deve incluir os seguintes cabeçalhos:
Cabeçalho Descrição x-amz-content-sha256Esse cabeçalho é obrigatório para todas as solicitações do AWS Signature Version 4. Defina o valor como
STREAMING-AWS4-HMAC-SHA256-PAYLOADpara indicar que a assinatura cobre somente cabeçalhos e que não há carga útil.Content-EncodingDefina o valor como
aws-chunked.O Amazon S3 oferece suporte a vários valores de codificação de conteúdo. Você pode especificar a codificação de conteúdo personalizada ao usar a API de streaming do Signature Version 4.
Por exemplo:
Content-Encoding : aws-chunked,gzipO Amazon S3 armazena o objeto resultante sem o valor
aws-chunkedno cabeçalhocontent-encoding. Seaws-chunkedfor o único valor transmitido no cabeçalhocontent-encoding, o S3 vai considerar o cabeçalhocontent-encodingvazio e não vai retornar esse cabeçalho quando você recuperar o objeto.x-amz-decoded-content-lengthDefina o valor como o tamanho, em bytes, dos dados a serem fragmentados, sem contar nenhum metadado. Por exemplo, se você estiver carregando um arquivo de 4 GB, defina o valor como 4294967296. Esse é o tamanho bruto do objeto a ser carregado (dados que você deseja armazenar no Amazon S3). Content-LengthDefina o valor como o tamanho real do corpo HTTP transmitido, que inclui o tamanho dos seus dados (valor definido para
x-amz-decoded-content-length), além dos metadados de fragmento. Cada fragmento tem metadados, como a assinatura do fragmento anterior. Os cálculos de fragmentos serão discutidos na seção a seguir. Se você incluir o cabeçalhoTransfer-Encodinge especificar qualquer valor diferente deidentity, não inclua o cabeçalhoContent-Length.
Envie o primeiro fragmento com a assinatura inicial. Você deve construir o fragmento conforme descrito na seção a seguir.
Definição do corpo do fragmento
Todos os fragmentos incluem alguns metadados. Cada fragmento deve estar de acordo com a seguinte estrutura:
string(IntHexBase(chunk-size)) + ";chunk-signature=" +signature+ \r\n +chunk-data+ \r\n
Em que:
-
IntHexBase()é uma função gravada para converter um tamanho de fragmento inteiro em hexadecimal. Por exemplo, se o tamanho do fragmento for 65536, a string hexadecimal será “10000”. -
chunk-sizeé o tamanho, em bytes, dos dados do fragmento, sem metadados. Por exemplo, se estiver carregando um objeto de 65 KB e usando um tamanho de fragmento de 64 KB, você carregará os dados em três fragmentos: o primeiro teria 64 KB, o segundo 1 KB e o fragmento final com 0 bytes. -
signaturePara cada fragmento, você calcula a assinatura usando a seguinte string a ser assinada. Para o primeiro fragmento, você usa a assinatura inicial como a assinatura anterior.
O tamanho dos dados do fragmento final que você envia é 0, embora o corpo do fragmento ainda contenha metadados, incluindo a assinatura do fragmento anterior.
Exemplo: objeto PUT
Você pode usar os exemplos desta seção como uma referência para verificar os cálculos de assinatura no seu código. Antes de analisar os exemplos, observe o seguinte:
-
Os cálculos de assinatura nesses exemplos usam os seguintes exemplos de credenciais de segurança.
Parâmetro Valor AWSAccessKeyIdAKIAIOSFODNN7EXAMPLEAWSSecretAccessKeywJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY -
Todos os exemplos usam o carimbo de data/hora de solicitação 20130524T000000Z (
Fri, 24 May 2013 00:00:00 GMT). -
Todos os exemplos usam
examplebucketcomo nome do bucket. -
Presume-se que o bucket esteja na região Leste dos EUA (Norte da Virgínia) e a credencial
Scopee os cálculos deSigning Keyusemus-east-1como especificador da região. Para obter mais informações, consulte Regiões e endpoints na Referência geral da Amazon Web Services. -
Você pode usar solicitações no estilo de caminho ou no estilo hospedado virtual. Os exemplos a seguir usam solicitações de 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.
O exemplo a seguir envia uma solicitação PUT para fazer upload de um objeto. Os cálculos de assinatura presumem o seguinte:
-
Você está fazendo o upload de um arquivo de texto de 65 KB, e o conteúdo do arquivo é uma string de um único caractere composta pela letra ‘a’.
-
O fragmento tem 64 KB. Como resultado, a carga útil é carregada em três fragmentos: 64 KB, 1 KB e o fragmento final com 0 bytes de dados.
-
O objeto resultante tem o nome de chave
chunkObject.txt. -
Você está solicitando
REDUCED_REDUNDANCYcomo classe de armazenamento adicionando o cabeçalho de solicitaçãox-amz-storage-class.
Para obter informações sobre a ação da API, consulte PutObject. A sintaxe de solicitação geral é a seguinte:
PUT /examplebucket/chunkObject.txt HTTP/1.1 Host: s3.amazonaws.com x-amz-date: 20130524T000000Z x-amz-storage-class: REDUCED_REDUNDANCY Authorization:SignatureToBeCalculatedx-amz-content-sha256: STREAMING-AWS4-HMAC-SHA256-PAYLOAD Content-Encoding: aws-chunked x-amz-decoded-content-length: 66560 Content-Length: 66824<Payload>
As etapas a seguir mostram cálculos de assinatura.
-
Assinatura inicial — Criar uma string a ser assinada
-
CanonicalRequest
PUT /examplebucket/chunkObject.txt content-encoding:aws-chunked content-length:66824 host:s3.amazonaws.com x-amz-content-sha256:STREAMING-AWS4-HMAC-SHA256-PAYLOAD x-amz-date:20130524T000000Z x-amz-decoded-content-length:66560 x-amz-storage-class:REDUCED_REDUNDANCY content-encoding;content-length;host;x-amz-content-sha256;x-amz-date;x-amz-decoded-content-length;x-amz-storage-class STREAMING-AWS4-HMAC-SHA256-PAYLOADNa solicitação canônica, a terceira linha está vazia, pois não há parâmetros de consulta na solicitação. A última linha é a string constante fornecida como o valor da carga útil com hash, que deve ser igual ao valor de
x-amz-content-sha256 header. -
StringToSign
AWS4-HMAC-SHA256 20130524T000000Z 20130524/us-east-1/s3/aws4_request cee3fed04b70f867d036f722359b0b1f2f0e5dc0efadbc082b76c4c60e316455nota
Para obter informações sobre cada linha na string a ser assinada, consulte o diagrama que explica o cálculo da assinatura inicial.
-
-
SigningKey
signing key = HMAC-SHA256(HMAC-SHA256(HMAC-SHA256(HMAC-SHA256("AWS4" + "<YourSecretAccessKey>","20130524"),"us-east-1"),"s3"),"aws4_request") -
Assinatura inicial
4f232c4386841ef735655705268965c44a0e4690baa4adea153f7db9fa80a0a9 -
Cabeçalho de autorização
O cabeçalho de autorização resultante é o seguinte:
AWS4-HMAC-SHA256 Credential=AKIAIOSFODNN7EXAMPLE/20130524/us-east-1/s3/aws4_request,SignedHeaders=content-encoding;content-length;host;x-amz-content-sha256;x-amz-date;x-amz-decoded-content-length;x-amz-storage-class,Signature=4f232c4386841ef735655705268965c44a0e4690baa4adea153f7db9fa80a0a9 -
Fragmento 1: (65536 bytes, com valor 97 para a letra ‘a’)
-
String do fragmento a ser assinada:
AWS4-HMAC-SHA256-PAYLOAD 20130524T000000Z 20130524/us-east-1/s3/aws4_request 4f232c4386841ef735655705268965c44a0e4690baa4adea153f7db9fa80a0a9 e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 bf718b6f653bebc184e1479f1935b8da974d701b893afcf49e701f3e2f9f9c5anota
Para obter informações sobre cada linha na string a ser assinada, consulte o diagrama anterior que mostra vários componentes da string a ser assinada (por exemplo, as últimas três linhas são
previous-signature,hash("")ehash(current-chunk-data)). -
Assinatura do fragmento:
ad80c730a21e5b8d04586a2213dd63b9a0e99e0e2307b0ade35a65485a288648 -
Dados do fragmento enviados:
10000;chunk-signature=ad80c730a21e5b8d04586a2213dd63b9a0e99e0e2307b0ade35a65485a288648 <65536-bytes>
-
-
Fragmento 2: (1024 bytes, com valor 97 para a letra ‘a’)
-
String do fragmento a ser assinada:
AWS4-HMAC-SHA256-PAYLOAD 20130524T000000Z 20130524/us-east-1/s3/aws4_request ad80c730a21e5b8d04586a2213dd63b9a0e99e0e2307b0ade35a65485a288648 e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 2edc986847e209b4016e141a6dc8716d3207350f416969382d431539bf292e4a -
Assinatura do fragmento:
0055627c9e194cb4542bae2aa5492e3c1575bbb81b612b7d234b86a503ef5497 -
Dados do fragmento enviados:
400;chunk-signature=0055627c9e194cb4542bae2aa5492e3c1575bbb81b612b7d234b86a503ef5497 <1024 bytes>
-
-
Fragmento 3: (0 bytes de dados)
-
String do fragmento a ser assinada:
AWS4-HMAC-SHA256-PAYLOAD 20130524T000000Z 20130524/us-east-1/s3/aws4_request 0055627c9e194cb4542bae2aa5492e3c1575bbb81b612b7d234b86a503ef5497 e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 -
Assinatura do fragmento:
b6c6ea8a5354eaf15b3cb7646744f4275b71ea724fed81ceb9323e279d449df9 -
Dados do fragmento enviados:
0;chunk-signature=b6c6ea8a5354eaf15b3cb7646744f4275b71ea724fed81ceb9323e279d449df9
-