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 AWS SigV4 para assinar solicitações de API, consulte Exemplos de assinatura de solicitação.
A tabela a seguir descreve as funções usadas no processo de criação de uma solicitação assinada. É 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. Esta é a assinatura final quando você assina com o SigV4. |
|
Assinatura do Algoritmo de assinatura digital de curva elíptica (ECDSA) calculada usando assinaturas assimétricas baseadas em criptografia de chave pública-privada. |
|
Um KDF NIST SP800-108 no Modo Contador usando a função PRF HMAC-SHA256, conforme definido no NIST SP 800-108r1 |
|
Uma função de octeto para inteiro, conforme descrito no ANSI X9.62. |
|
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 as solicitações, você pode usar o AWS SigV4 ou o AWS SigV4a. A principal diferença entre os dois está na forma como a assinatura é calculada. Com o SigV4a, o conjunto de regiões é incluído na string a ser assinada, mas não faz parte da etapa de derivação da credencial.
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
Criar 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
Use a chave de acesso secreta para derivar a chave usada para assinar a solicitação.
Calcular a assinatura
Realize uma operação de hash com chave 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
. -
Para SigV4a, você deve incluir um cabeçalho de conjunto de regiões que especifique o conjunto de regiões em que a solicitação será válida. O cabeçalho
X-Amz-Region-Set
é especificado como uma lista de valores separados por vírgula. O exemplo a seguir mostra um cabeçalho de região que permite fazer uma solicitação nas regiões us-east-1 e us-west-1.X-Amz-Region-Set=us-east-1,us-west-1
Você pode usar curingas (*) em regiões para especificar várias regiões. No exemplo a seguir, o cabeçalho permite que uma solicitação seja feita tanto na região us-west-1 quanto na us-west-2.
X-Amz-Region-Set=us-west-*
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, considere incluir os cabeçalhos adicionais no cálculo da assinatura.Não inclua cabeçalhos hop-by-hop que são alterados com frequência durante o trânsito em um sistema complexo. Isso inclui todos os cabeçalhos de transporte voláteis que são alterados por proxies, balanceadores de carga e nós em um sistema distribuído, incluindo
connection
,x-amzn-trace-id
,user-agent
,keep-alive
,transfer-encoding
,TE
,trailer
,upgrade
,proxy-authorization
eproxy-authenticate
. -
-
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.-
SigV4: use
AWS4-HMAC-SHA256
para especificar o algoritmo de hashHMAC-SHA256
. -
SigV4a: use
AWS4-ECDSA-P256-SHA256
para especificar o algoritmo de hashECDSA-P256-SHA-256
.
-
-
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.-
SigV4: as credenciais incluem o ID da chave de acesso, a data no formato
YYYYMMDD
, o código da região, o código do serviço e a stringaws4_request
de término separados por barras (/). O código da região, o código do serviço e a string de término devem usar caracteres minúsculos. A string tem o seguinte formato:YYYYMMDD/region/service/aws4_request
. -
SigV4a: as credenciais incluem a data no formato
YYYYMMDD
, o nome do serviço e a stringaws4_request
de término separados por barras (/). Observe que o escopo da credencial não inclui a região, pois ela é englobada em um cabeçalhoX-Amz-Region-Set
separado. A string tem o seguinte formato:YYYYMMDD/service/aws4_request
.
-
-
HashedCanonicalRequest
: o hash da solicitação canônica, calculada na etapa anterior.
Veja a seguir um exemplo de string para assinar.
"<Algorithm>
" + "\n" +
timeStampISO8601Format + "\n" +
<Scope>
+ "\n" +
Hex(<Algorithm>
(<CanonicalRequest>
))
Derivar uma chave de assinatura
Para derivar uma chave de assinatura, escolha um dos processos a seguir para calcular uma chave de assinatura para SigV4 ou SigV4a.
Derivar uma chave de assinatura para SigV4
Para derivar uma chave de assinatura para SigV4, realize uma sequência de operações de hash com chave (HMAC) no serviço, região e data da solicitaçã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.
Derivar uma chave de assinatura para SigV4
-
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")
Derivar uma chave de assinatura para SigV4a
Para criar uma chave de assinatura para SigV4a, use o processo a seguir para derivar um par de chaves da chave de acesso secreta. Para obter um exemplo de implementação dessa derivação, consulte a implementação da biblioteca C99 da autenticação do lado do cliente da AWS
n = [NIST P-256 elliptic curve group order] G = [NIST P-256 elliptic curve base point] label = "AWS4-ECDSA-P256-SHA256" akid = [AWS access key ID as a UTF8 string] sk = [AWS secret access Key as a UTF8 Base64 string] input_key = "AWS4A" || sk count = 1 while (counter != 255) { context = akid || counter
// note: counter is one byte
key = KDF(input_key, label, context, 256) c = Oct2Int(key) if (c > n - 2) { counter++ } else { k = c + 1// private key
Q = k * G// public key
} } if (c < 255) { return [k, Q] } else { return FAILURE }
Calcular a assinatura
Depois de derivar a chave de assinatura, calcule a assinatura para adicionar à sua solicitação. Esse procedimento varia de acordo com a versão de assinatura que você usa.
Para calcular uma assinatura para SigV4
-
Chame a função de hash com o resultado da chamada anterior como a chave e a string para assinar como os dados. Use a chave de assinatura derivada como a chave de hash para esta operação. 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.
Para calcular uma assinatura para SigV4a
-
Usando o algoritmo de assinatura digital (ECDSA P-256), assine a string para assinar que você criou na etapa anterior. A chave usada para essa assinatura é a chave assimétrica privada derivada da chave de acesso secreta, conforme descrito acima.
signature = base16(
ECDSA-Sign
(k,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
SigV4
O exemplo a seguir mostra um cabeçalho Authorization
para a ação DescribeInstances
usando o AWS SigV4. 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
Sigv4a
O exemplo a seguir mostra um cabeçalho Authorization para a ação CreateBucket
usando o AWS SigV4a. 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 a credencial. Porém, os outros elementos devem ser separados por vírgulas.
Authorization: AWS4-ECDSA-P256-SHA256
Credential=AKIAIOSFODNN7EXAMPLE/20220830/s3/aws4_request,
SignedHeaders=host;x-amz-date;x-amz-region-set,
Signature=calculated-signature
exemplo Exemplo: solicitação com parâmetros de autenticação na string de consulta
SigV4
O exemplo a seguir mostra uma consulta para a ação DescribeInstances
usando o AWS SigV4 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
Sigv4a
O exemplo a seguir mostra uma consulta para a ação CreateBucket
usando o AWS SigV4a 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=CreateBucket&
Version=2016-11-15&
X-Amz-Algorithm=AWS4-ECDSA-P256-SHA256&
X-Amz-Credential=AKIAIOSFODNN7EXAMPLE/20220830/s3/aws4_request&
X-Amz-Region-Set=us-west-1&
X-Amz-Date=20220830T123600Z&
X-Amz-SignedHeaders=host;x-amz-date;x-amz-region-set&
X-Amz-Signature=calculated-signature