Crie uma solicitação assinada de API da AWS
Importante
Caso use um SDK da AWS (consulte Código de exemplo e bibliotecas
Em regiões compatíveis com várias versões de assinatura, assinar as solicitações manualmente significa que é necessário especificar qual versão de assinatura está sendo usada. Quando você fornece solicitações para pontos de acesso multirregionais, os SDKs e a CLI automaticamente alternam para o uso do Signature Version 4A, sem configuração adicional.
Você pode usar o protocolo de assinatura SigV4 da AWS para criar uma solicitação assinada para solicitações de API da AWS.
-
A criação de uma solicitação canônica com base nos detalhes da solicitação.
-
O cálculo uma assinatura usando suas credenciais da AWS.
-
Adicionar essa assinatura à solicitação como um cabeçalho de autorização.
A AWS, em seguida, replica esse processo e verifica a assinatura, concedendo ou negando o acesso adequadamente.
Para ver como você pode usar o SigV4 da AWS para assinar solicitações de API, consulte Exemplos de assinatura de solicitação
O diagrama a seguir ilustra o processo de assinatura do SigV4, incluindo os vários componentes da string criada para assinatura.
A tabela a seguir descreve as funções exibidas no diagrama. É necessário implementar o código para essas funções. Para obter mais informações, consulte os exemplos de código nos AWS SDKs.
Função | Descrição |
---|---|
|
Converta a string em letras minúsculas. |
|
Codificação de base 16 em letras minúsculas. |
|
Função de hash criptográfico do Secure Hash Algorithm (SHA). |
|
Calcula o HMAC usando o algoritmo SHA256 com a chave de assinatura fornecida. Essa é a assinatura final. |
|
Remova qualquer espaço em branco inicial e final. |
|
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. Para ver um exemplo de uma função UriEncode em Java, consulte Java Utilities |
nota
Ao assinar suas solicitações, você pode usar o AWS Signature Version 4 ou o AWS Signature Version 4A. A principal diferença entre os dois está na forma como a assinatura é calculada. Com o AWS Signature Version 4A, a assinatura não inclui informações específicas da região e é calculada usando o algoritmo AWS4-ECDSA-P256-SHA256
.
Solicitação de assinatura com credenciais de segurança temporárias
Em vez de usar credenciais de longo prazo para assinar uma solicitação, é possível usar credenciais de segurança temporárias fornecidas pelo AWS Security Token Service (AWS STS).
Ao usar credenciais de segurança temporárias, é necessário adicionar o código X-Amz-Security-Token
ao cabeçalho de autorização ou incluí-lo na string de consulta para manter o token da sessão. Alguns serviços exigem que você adicione X-Amz-Security-Token
à solicitação canônica. Outros serviços exigem apenas que você adicione X-Amz-Security-Token
no final, depois de calcular a assinatura. Verifique a documentação de cada AWS service (Serviço da AWS) para obter requisitos específicos.
Resumo das etapas de assinatura
Crie uma solicitação canônica:
Organize o conteúdo da solicitação (host, ação, cabeçalhos etc.) em um formato padrão canônico. A solicitação canônica é um recurso usado para criar a string para assinar. Para obter detalhes sobre a criação da solicitação canônica, consulte Elementos de uma assinatura de solicitação de API da AWS.
Criar um hash para a solicitação canônica
Faça o hash da solicitação canônica usando o mesmo algoritmo que você usou para criar o hash da carga útil. O hash da solicitação canônica é uma string de caracteres hexadecimais em minúsculas.
Criar uma string para assinar
Crie uma string para assinar com a solicitação canônica e informações adicionais, como o algoritmo, data de solicitação, escopo de credencial e o hash da solicitação canônica.
Derivar uma chave de assinatura
Realize uma sequência de operações de hash com chave (HMAC) na data da solicitação, região e serviço, usando sua chave de acesso secreta da AWS como a chave para a operação inicial de hashing.
Calcular a assinatura
Realize uma operação de hash com chave (HMAC) na string para assinar usando a chave de assinatura derivada como a chave de hash.
Adicionar a assinatura à solicitação
Adicione a assinatura calculada a um cabeçalho de HTTP ou à string de consulta da solicitação.
Criar uma solicitação canônica
Para criar uma solicitação canônica, concatene as strings a seguir separadas por caracteres de linha nova. Isso ajuda a garantir que a assinatura que você calcula possa corresponder à assinatura que a AWS calcula.
<HTTPMethod>
\n<CanonicalURI>
\n<CanonicalQueryString>
\n<CanonicalHeaders>
\n<SignedHeaders>
\n<HashedPayload>
-
HTTPMethod
: o método HTTP, comoGET
,PUT
,HEAD
eDELETE
. -
CanonicalUri
: a versão codificada em URI do componente de caminho absoluto do URI, começando com o código/
que segue o nome do domínio e indo até o final da string ou até o caractere de ponto de interrogação (?
) se você tiver parâmetros de string de consulta. Se o caminho absoluto estiver vazio, use um caractere de barra inclinada (/
). O URI no exemplo a seguir,/amzn-s3-demo-bucket/myphoto.jpg
, é o caminho absoluto, e você não codifica o/
no caminho absoluto:http://s3.amazonaws.com/amzn-s3-demo-bucket/myphoto.jpg
-
CanonicalQueryString
: os parâmetros da string de consulta codificados por URI. Codifique por URI cada nome e valor 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 é:http://s3.amazonaws.com/amzn-s3-demo-bucket?prefix=somePrefix&marker=someMarker&max-keys=2
A 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-recursoACL
no bucketamzn-s3-demo-bucket
:http://s3.amazonaws.com/amzn-s3-demo-bucket?acl
Nesse caso, a CanonicalQueryString seria:
UriEncode("acl") + "=" + ""
Caso o URI não contenha 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 caractere de linha nova ("\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 linha nova ("\n"
). Veja a seguir um exemplo de um CanonicalHeader:Lowercase(
<HeaderName1>
)+":"+Trim(<value>
)+"\n" Lowercase(<HeaderName2>
)+":"+Trim(<value>
)+"\n" ... Lowercase(<HeaderNameN>
)+":"+Trim(<value>
)+"\n"A lista CanonicalHeaders deve conter:
-
Cabeçalho HTTP
host
-
Se o cabeçalho
Content-Type
estiver 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-token
na solicitação. É necessário adicionar esse cabeçalho à lista deCanonicalHeaders
.
nota
O cabeçalho
x-amz-content-sha256
é obrigatório para solicitações da AWS do Amazon S3. Ele fornece um hash da carga da solicitação. Se não houver carga útil, será necessário fornecer o hash de uma string vazia.Todo nome de cabeçalho deve:
-
usar caracteres minúsculos.
-
ser exibido em ordem alfabética.
-
ser seguido por dois pontos (
:
).
Para valores, é necessário:
-
remover todos os espaços à esquerda ou à direita.
-
converter espaços sequenciais em um espaço único.
-
separar os valores de um cabeçalho de múltiplos valores usando vírgulas.
-
É necessário incluir na assinatura o cabeçalho host (HTTP/1.1) ou o cabeçalho :authority (HTTP/2) e quaisquer cabeçalhos
x-amz-*
. Opcionalmente, você pode incluir outros cabeçalhos padrão na assinatura, como content-type.
As funções
Lowercase()
eTrim()
usadas neste exemplo estão descritas na seção anterior.Veja a seguir um exemplo de string
CanonicalHeaders
. O nomes dos cabeçalhos estão em letras minúsculas e são classificados.host:s3.amazonaws.com x-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 x-amz-date:20130708T220855Z
nota
Para fins de cálculo de uma assinatura de autorização, somente o host e cabeçalhos
x-amz-*
são obrigatórios; no entanto, para evitar a adulteração de dados, convém incluir todos os cabeçalhos no cálculo da assinatura. -
-
SignedHeaders
: uma lista ordenada alfabeticamente, 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
. Para o exemplo anterior, o valor deSignedHeaders
seria:host;x-amz-content-sha256;x-amz-date
-
HashedPayload
: uma string criada usando a carga útil no corpo da solicitação HTTP como entrada para uma função de hash. Esta string usa caracteres hexadecimais minúsculos.Hex(SHA256Hash(
<payload>
>))Se não houver carga útil na solicitação, calcule um hash da string vazia. Por exemplo, ao recuperar um objeto usando uma solicitação
GET
, não haverá nada na carga útil.Hex(SHA256Hash(""))
nota
Para o Amazon S3, inclua a string literal
UNSIGNED-PAYLOAD
ao construir uma solicitação canônica e defina o mesmo valor como o cabeçalhox-amz-content-sha256
ao enviar a solicitação.Hex(SHA256Hash("UNSIGNED-PAYLOAD"))
Criar um hash para a solicitação canônica
Crie um hash (resumo) da solicitação canônica usando o mesmo algoritmo que você usou para criar o hash da carga útil. O hash da solicitação canônica é uma string de caracteres hexadecimais em minúsculas.
Criar uma string para assinar
Para criar uma string para assinar, concatene as strings a seguir separadas por caracteres de linha nova. Não termine esta string com um caractere de linha nova.
Algorithm
\n
RequestDateTime
\n
CredentialScope
\n
HashedCanonicalRequest
-
Algorithm
: o algoritmo usado para criar o hash da solicitação canônica. Para SHA-256, o algoritmo éAWS4-HMAC-SHA256
. -
RequestDateTime
: a data e a hora usadas no escopo da credencial. Esse valor é a hora UTC atual no formato ISO 8601 (por exemplo,20130524T000000Z
). -
CredentialScope
: o escopo de credencial, que restringe a assinatura resultante à região e ao serviço especificados. A string tem o seguinte formato:AAAAMMDD
/região
/serviço
/aws4_request. -
HashedCanonicalRequest
: o hash da solicitação canônica, calculada na etapa anterior.
Veja a seguir um exemplo de string para assinar.
"AWS4-HMAC-SHA256" + "\n" +
timeStampISO8601Format + "\n" +
<Scope>
+ "\n" +
Hex(SHA256Hash(<CanonicalRequest>
))
Derivar uma chave de assinatura
Para derivar uma chave de assinatura, realize uma sequência de operações de hash com chave (HMAC) na data da solicitação, região e serviço, usando sua chave de acesso secreta da AWS como a chave para a operação inicial de hashing.
Para cada etapa, chame a função de hash com a chave e os dados necessários. O resultado de cada chamada para a função de hash torna-se a entrada para a próxima chamada para a função de hash.
O exemplo a seguir mostra como você deriva a SigningKey
usada na próxima seção desse procedimento, mostrando a ordem na qual sua entrada é concatenada e transformada em hash. O código HMAC-SHA256
é a função de hash usada para fazer o hash dos dados, conforme mostrado.
DateKey = HMAC-SHA256("AWS4"+"
<SecretAccessKey>
", "<YYYYMMDD>
") DateRegionKey = HMAC-SHA256(<DateKey>
, "<aws-region>
") DateRegionServiceKey = HMAC-SHA256(<DateRegionKey>
, "<aws-service>
") SigningKey = HMAC-SHA256(<DateRegionServiceKey>
, "aws4_request")
Entrada obrigatória
-
Key
, uma string que contém sua chave de acesso secreta. -
Date
, uma string que contém a data usada no escopo da credencial, no formato AAAAMMDD. -
Region
, uma string que contém o código da região (por exemplo,us-east-1
).Para obter uma lista de regiões de strings, consulte Regional endpoints, na Referência geral da AWS.
-
Service
, uma string que contém o código do serviço (por exemplo,ec2
). -
A string para assinar que você criou na etapa anterior.
Para derivar uma chave de assinatura
-
Concatene
"AWS4"
e a chave de acesso secreta. Chame a função de hash com a string concatenada como chave e a string de data como os dados.DateKey = hash("AWS4" + Key, Date)
-
Chame a função de hash com o resultado da chamada anterior como chave e a string de região como os dados.
DateRegionKey = hash(kDate, Region)
-
Chame a função de hash com o resultado da chamada anterior como a chave e a string de serviço como os dados.
O código do serviço é definido pelo serviço. Você pode usar get-products
na AWS Pricing CLI para retornar o código de serviço de um serviço. DateRegionServiceKey = hash(kRegion, Service)
-
Chame a função de hash com o resultado da chamada anterior como a chave e “aws4_request” como os dados.
SigningKey = hash(kService, "aws4_request")
Calcular a assinatura
Depois de derivar a chave de assinatura, calcule-a realizando uma operação de hash de chave na string a ser assinada. Use a chave de assinatura derivada como a chave de hash para esta operação.
Para calcular uma assinatura
-
Chame a função de hash com o resultado da chamada anterior como a chave e a string para assinar como os dados. O resultado é a assinatura como valor binário.
signature = hash(SigningKey,
string-to-sign
) -
Converta a assinatura da representação binária em hexadecimal, em caracteres minúsculos.
Adicionar a assinatura à solicitação
Adicione a assinatura calculada à sua solicitação.
exemplo Exemplo: cabeçalho de autorização
O exemplo a seguir mostra um cabeçalho Authorization
para a ação DescribeInstances
. Para facilitar a leitura, este exemplo está formatado com quebras de linha. Em seu código, deve ser uma string contínua. Não há vírgula entre o algoritmo e Credential
. Porém, os outros elementos devem ser separados por vírgulas.
Authorization: AWS4-HMAC-SHA256
Credential=AKIAIOSFODNN7EXAMPLE/20220830/us-east-1/ec2/aws4_request,
SignedHeaders=host;x-amz-date,
Signature=calculated-signature
exemplo Exemplo: solicitação com parâmetros de autenticação na string de consulta
O exemplo a seguir mostra uma consulta para a ação DescribeInstances
que contém as informações de autenticação. Para facilitar a leitura, esse exemplo está formatado com quebras de linha e não codificado de URL. Em seu código, a string de consulta deve ser uma string contínua codificada de URL.
https://ec2.amazonaws.com/?
Action=DescribeInstances&
Version=2016-11-15&
X-Amz-Algorithm=AWS4-HMAC-SHA256&
X-Amz-Credential=AKIAIOSFODNN7EXAMPLE/20220830/us-east-1/ec2/aws4_request&
X-Amz-Date=20220830T123600Z&
X-Amz-SignedHeaders=host;x-amz-date&
X-Amz-Signature=calculated-signature