Política HMAC

Esta página se aplica à Apigee e à Apigee híbrida.

Confira a documentação da Apigee Edge.

Ícone da política

Esta política calcula e, opcionalmente, verifica um código de autenticação de mensagens baseado em hash (HMAC, na sigla em inglês). Também conhecido como código de autenticação de mensagens com chave ou hash com chave, o HMAC usa uma função de hash criptográfico como SHA-1, SHA-224, SHA-256, SHA-384, SHA-512 ou MD-5, aplicada a uma "mensagem", com uma chave secreta, para produzir um código de autenticação de assinatura ou mensagem nela. O termo "mensagem" refere-se a qualquer streaming de bytes. No uso típico de HMAC, um remetente de uma mensagem envia uma mensagem e o respectivo HMAC para um destinatário, e o destinatário pode usar o HMAC com a chave secreta compartilhada para autenticar a mensagem.

Esta é uma política padrão e pode ser implantada em qualquer tipo de ambiente. Para informações sobre os tipos de políticas e a disponibilidade de cada tipo de ambiente, consulte Tipos de políticas.

Para saber mais sobre o HMAC, consulte HMAC: Keyed-Hashing for Message Authentication (rfc2104).

Amostras

Gerar HMAC

<HMAC name='HMAC-1'>

  <Algorithm>SHA256</Algorithm>

  <!-- the default encoding of the SecretKey is UTF-8 -->
  <SecretKey encoding='base64' ref='private.secretkey'/>

  <IgnoreUnresolvedVariables>true|false</IgnoreUnresolvedVariables> <!-- optional -->

  <!--
    The Message element accepts a template, which means the "message" the policy operates
    on can include fixed and multiple variable parts, including newlines and static functions.
    Whitespace, such as newlines and space characters, is significant.
   -->
  <Message>Fixed Part
{a_variable}
{timeFormatUTCMs(timeFormatString1,system.timestamp)}
{nonce}</Message>

  <!-- default encoding is base64 -->
  <Output encoding='base16'>name_of_variable</Output>

</HMAC>

Verificar HMAC

<HMAC name='HMAC-1'>

  <Algorithm>SHA256</Algorithm>

  <!-- the default encoding of the SecretKey is UTF-8 -->
  <SecretKey encoding='base16' ref='private.secretkey'/>

  <IgnoreUnresolvedVariables>true|false</IgnoreUnresolvedVariables> <!-- optional -->

  <!--
     The Message element accepts a template. This policy verifies an HMAC on the request content.
   -->
  <Message>{request.content}</Message>

  <!--
    VerificationValue is optional.
    Include it to perform an HMAC check.
  -->
  <VerificationValue encoding='base16' ref='expected_hmac_value'/>

  <!-- default encoding of the output is base64 -->
  <Output encoding='base16'>name_of_variable</Output>

</HMAC>

A computação de uma assinatura e a verificação dessa assinatura seguem exatamente o mesmo processo. A política HMAC calcula um HMAC e, opcionalmente, pode verificar a assinatura calculada com um valor esperado. O elemento VerificationValue opcional (se presente) direciona a política para verificar o valor calculado em relação a um valor conhecido ou fornecido.


Referência de elementos para HMAC

A referência de política descreve os elementos e atributos da política HMAC.

Atributos que se aplicam ao elemento de nível superior

<HMAC name="HMAC" continueOnError="false" enabled="true" async="false">

Os seguintes atributos são comuns a todos os elementos pai de política.

Atributo Descrição Padrão Presence
nome O nome interno da política. Os caracteres que podem ser usados no nome são restritos a: A-Z0-9._\-$ %. No entanto, a IU da Apigee impõe outras restrições, como a remoção automática de caracteres que não são alfanuméricos.

Opcionalmente, use o elemento <DisplayName> para rotular a política no editor de proxy da IU da Apigee com um nome de linguagem natural diferente.

N/A Obrigatório
continueOnError Defina como false para retornar um erro quando uma política falhar. Esse é o comportamento esperado na maioria das políticas.

Defina como true para que a execução do fluxo continue mesmo depois que uma política falhar. Consulte também:

false Opcional
ativado Defina como true para aplicar a política.

Defina como false para "desativar" a política. A política não será aplicada mesmo se permanecer anexada a um fluxo.

true Opcional
async Esse atributo está obsoleto. false Descontinuado

<Algorithm>

<Algorithm>algorithm-name</Algorithm>

Especifica o algoritmo de hash a ser usado ao calcular o HMAC.

Padrão N/A
Presence Obrigatório
Tipo String
Valores válidos SHA-1, SHA-224, SHA-256, SHA-384, SHA-512, e MD-5

A configuração da política aceita nomes de algoritmo sem distinção entre maiúsculas e minúsculas e com ou sem o traço entre as letras e os números. Por exemplo, SHA256 e SHA-256 e sha256 são equivalentes.

<DisplayName>

<DisplayName>Policy Display Name</DisplayName>

Use além do atributo name para rotular a política no editor de proxy da IU da Apigee com um nome de linguagem natural diferente.

Padrão Se você omitir esse elemento, o valor do atributo name da política será usado.
Presence Opcional
Tipo String

<Message>

<Message>message_template_here</Message>
or
<Message ref='variable_here'/>

Especifica o payload da mensagem a ser assinado. A entrada desse elemento é compatível com os modelos de mensagem (substituição de variáveis) para permitir que outros itens sejam incluídos no ambiente de execução, como carimbos de data/hora, valores de uso único, listas de cabeçalhos ou outras informações. Exemplo:

<Message>Fixed Part
    {a_variable}
    {timeFormatUTCMs(timeFormatString1,system.timestamp)}
    {nonce}
</Message>

O modelo de mensagem pode incluir partes fixas e variáveis, incluindo novas linhas e funções estáticas. O espaço em branco, como novas linhas e caracteres, é importante.

Padrão N/A
Presence Obrigatório
Tipo String
Valores válidos Qualquer string é válida para o valor de texto. Se você fornecer um atributo ref, ele terá precedência sobre o valor do texto. A política avalia o valor do texto ou a variável referenciada como um modelo de mensagem.

<Output>

<Output encoding='encoding_name'>variable_name</Output>

Especifica o nome da variável que a política precisa definir com o valor calculado HMAC. Também especifica a codificação a ser usada para a saída.

Padrão

A variável de saída padrão é hmac.POLICYNAME.output.

O valor padrão para o atributo encoding é base64.

Presence Opcional. Se esse elemento não estiver presente, a política definirá a variável de fluxo hmac.POLICYNAME.output com um valor codificado em base64.
Tipo String
Valores válidos

Para codificação, hex, base16, base64, base64url.

Os valores não diferenciam maiúsculas de minúsculas. Portanto, hex e base16 são sinônimos.

O valor de texto do elemento Output pode ser qualquer nome de variável de fluxo válido.

<SecretKey>

<SecretKey encoding='encoding_name' ref='private.secretkey'/>

Especifica a chave secreta usada para calcular o HMAC. A chave é obtida da variável referenciada, decodificada de acordo com a codificação específica.

Padrão

Não há valor padrão para a variável referenciada. O atributo ref é obrigatório.

Na ausência de um atributo encoding, a política decodifica a string da chave secreta com UTF-8 por padrão para receber os bytes da chave.

Presence Obrigatório
Tipo String
Valores válidos

Para encoding, os valores válidos são hex, base16, base64 e utf8. O padrão é UTF-8. Os valores não diferenciam maiúsculas de minúsculas, e os traços são insignificantes. Base16 é igual a base-16 e bAse16. Base16 e Hex são sinônimos.

O uso de um atributo de codificação permite que você especifique uma chave que inclua bytes fora do intervalo de caracteres imprimíveis em UTF-8. Por exemplo, suponha que a configuração da política inclua isto:

 <SecretKey encoding='hex' ref='private.encodedsecretkey'/>

E suponha que private.encodedsecretkey mantenha a string 536563726574313233.

Nesse caso, os bytes da chave serão decodificados como: [53 65 63 72 65 74 31 32 33] (cada byte representado em hexadecimal). Outro exemplo: se encoding='base64' for usado, e se private.encodedsecretkey mantiver a string U2VjcmV0MTIz, o resultado será o mesmo conjunto de bytes da chave. Sem um atributo de codificação ou com um atributo de codificação UTF8, o valor da string Secret123 resultaria no mesmo conjunto de bytes. Isso mostra três maneiras diferentes de representar a mesma chave.

<VerificationValue>

<VerificationValue encoding='encoding_name' ref='variable_name'/>
or
<VerificationValue encoding='encoding_name'>string_value</VerificationValue>

(Opcional) Especifica o valor da verificação e a codificação usados para codificar o valor de verificação. A política usará esse algoritmo para decodificar o valor.

Padrão Não há valor de verificação padrão. Se o elemento estiver presente, mas o atributo encoding estiver ausente, a política usará uma codificação padrão de base64
Presence Opcional
Tipo String
Valores válidos

Os valores válidos para o atributo de codificação são: hex, base16, base64 e base64url. Os valores não diferenciam maiúsculas de minúsculas. Portanto, hex e base16 são sinônimos.

A codificação de VerificationValue não precisa ser a mesma usada para o elemento Output.

<IgnoreUnresolvedVariables>

<IgnoreUnresolvedVariables>true|false</IgnoreUnresolvedVariables>

Defina como false se quiser que a política gere um erro quando qualquer variável referenciada especificada na política não for resolvível. Defina como true para tratar qualquer variável não resolvida como uma string vazia (null).

O booleano IgnoreUnresolvedVariables afeta apenas as variáveis referenciadas pelo modelo de mensagem. Embora SecretKey e VerificationValue possam fazer referência a uma variável, ambos precisam ser resolvidos, portanto, a configuração ignore não se aplica a eles.

Padrão Falso
Presence Opcional
Tipo Booleano
Valores válidos verdadeiro ou falso

Variáveis de fluxo

A política pode configurar essas variáveis durante a execução.

Variável Descrição Exemplo
hmac.policy_name.message A política define essa variável com a mensagem efetiva, o resultado da avaliação do modelo de mensagem especificado no elemento Message. hmac.HMAC-Policy.message = "Hello, World"
hmac.policy_name.output Recebe o resultado do cálculo HMAC, quando o elemento Output não especifica um nome de variável. hmac.HMAC-Policy.output = /yyRjydfP+fBHTwXFgc5AZhLAg2kwCri+e35girrGw4=
hmac.policy_name.outputencoding Recebe o nome da codificação de saída. hmac.HMAC-Policy.outputencoding = base64

Problemas comuns

A política de HMAC parece simples: forneça uma chave e uma mensagem, e receba um HMAC calculado em resposta. Pode ser frustrante usar a política se você receber um valor HMAC inesperado para uma combinação conhecida de mensagem e chave. Esta seção explica algumas notas de uso para solucionar esses problemas.

Há duas armadilhas comuns que resultam em HMACs incompatíveis durante a verificação: diferenças de espaços em branco na mensagem e diferenças na codificação e na decodificação. Este último se aplica ao elemento SecretKey, bem como ao elemento Output.

Diferenças de espaços em branco

Diferenças que podem parecer não relevantes para um humano afetam o valor de HMAC de saída. Por exemplo, suponha que uma chave secreta seja representada como "Secret123". Com a decodificação UTF-8, os bytes de chave serão: [53 65 63 72 65 74 31 32 33]. O uso dessa chave para calcular um HMAC-SHA256 na mensagem abc resulta em a7938720fe5749d31076e6961360364c0cd271443f1b580779932c244293bc94. A adição de um único espaço à mensagem para que seja abc<SPACE>, em que <SPACE> implica um ASCII 32, resulta em um HMAC-SHA256 de 274669b2a85d2532da48e2ce3d8e52ee17346d1bcd1a606d87db1934b5ab294b.

Da mesma forma, se a mensagem for abc<NEWLINE>, em que <NEWLINE> implica um ASCII 10, o HMAC será 0780370844ca07f896066837e8230d3b6a775f678a4ae03e6b5e864c674831f5. Pequenas mudanças na mensagem resultam em valores HMAC muito diferentes. Isso ocorre por design. Esse é um comportamento esperado e desejado do HMAC.

Atenção: é importante garantir que o corpo da mensagem usado para calcular o HMAC original e o corpo da mensagem usados para verificar o HMAC sejam exatamente os mesmos. Se o verificador de um HMAC mudar o payload da mensagem de alguma forma, adicionando qualquer espaço em branco ou reformatando o texto, o HMAC calculado mudará.

Tome cuidado especial ao usar um modelo de mensagem na configuração da política. Por exemplo, este fragmento de configuração de política mostra um possível problema:

<HMAC name='HMAC-1'>
    ...
    <!-- the result of this message template will include surrounding whitespace -->
    <Message>
        {request.content}
    </Message>
    ...
       
</HMAC>

O resultado da avaliação do modelo de mensagem no elemento <Message> incluirá novas linhas e espaços ao redor do conteúdo da mensagem. Isso não é exatamente o que você quer. Uma configuração melhor parecia como esta:

<HMAC name='HMAC-1'>
    ...
    <Message>{request.content}</Message>
    ...
         
</HMAC>

Diferenças na codificação

As diferentes decodificações do mesmo material da chave resultam em chaves diferentes. Suponha que uma chave secreta possa ser representada como "U2VjcmV0S2V5MTIz". Com a decodificação UTF-8, os bytes de chave representados em base16 serão: [55 32 56 6a 63 6d 56 30 53 32 56 35 4d 54 49 7a]. Com a decodificação em base64, os bytes da chave serão [53 65 63 72 65 74 4b 65 79 31 32 33]. A decodificação do material de origem resulta em chaves diferentes, e isso resultará em valores de HMAC distintos.

Atenção: é importante garantir que o material da chave usado para calcular o HMAC original e a chave usada para verificar o HMAC sejam exatamente os mesmos. Isso provavelmente significa garantir que a mesma codificação da chave seja usada em ambas as extremidades. Na política de HMAC, é possível usar o atributo encoding no elemento SecretKey para especificar a codificação da chave.

Considere também as codificações na saída. Um HMAC-SHA256 expresso em base16 ou codificação hexadecimal como 27f17e11c8ece93844c5eb5e55161d993368628a214f9a51c25d0185e8ea06e2 é igual a um HMAC-SHA256 expresso em formato codificado em Base64 como J/F+Ecjs6ThExeteVRYdmTNoYoohT5pRwl0BhejqBuI=. Eles parecem diferentes, mas essas duas strings representam o mesmo valor. Verifique se a mesma codificação é usada para codificar o HMAC calculado originalmente e o HMAC de verificação. Na política de HMAC, é possível usar o atributo encoding no elemento Output para especificar a codificação de saída desejada e o mesmo atributo no elemento VerificationValue para especificar como decodificar o verificador.

Referência de erros

Esta seção descreve os códigos de falha e as mensagens de erro que são retornadas e as variáveis de falha definidas pela Apigee quando essa política aciona um erro. Essas informações são importantes para saber se você está desenvolvendo regras de falha para lidar com falhas. Para saber mais, consulte O que você precisa saber sobre erros de política e Como lidar com falhas.

Erros de execução

Esses erros podem ocorrer quando a política é executada.

Código de falha Status HTTP Ocorre quando
steps.hmac.UnresolvedVariable 401

Esse erro ocorrerá se uma variável especificada na política de código de autenticação de mensagem baseado em hash (HMAC, na sigla em inglês):

  • Fora do escopo (não disponível no fluxo específico em que a política está sendo executada)

    ou

  • Não é possível resolver (não está definida)
steps.hmac.HmacVerificationFailed 401 A verificação de HMAC falhou. O valor de verificação fornecido não corresponde ao valor calculado.
steps.hmac.HmacCalculationFailed 401 A política não conseguiu calcular o HMAC.
steps.hmac.EmptySecretKey 401 O valor da variável da chave secreta está vazio.
steps.hmac.EmptyVerificationValue 401 A variável que contém o valor de verificação está vazia.

Erros na implantação

Esses erros podem ocorrer quando você implanta um proxy que contém esta política.

Nome do erro Status HTTP Ocorre quando
steps.hmac.MissingConfigurationElement 401 Esse erro ocorre quando um elemento ou atributo obrigatório está ausente.
steps.hmac.InvalidValueForElement 401 Esse erro ocorrerá se o valor especificado no elemento algoritmo não for um dos seguintes valores: SHA-1, SHA-224, SHA-256, SHA-512 ou MD-5.
steps.hmac.InvalidSecretInConfig 401 Esse erro ocorre quando há um valor de texto explicitamente fornecido para SecretKey.
steps.hmac.InvalidVariableName 401 Esse erro ocorre se a variável SecretKey não contiver o prefixo private (private.).

Fault variables

These variables are set when a runtime error occurs. For more information, see What you need to know about policy errors.

Variables Where Example
fault.name="fault_name" fault_name is the name of the fault, as listed in the Runtime errors table above. The fault name is the last part of the fault code. fault.name Matches "UnresolvedVariable"
hmac.policy_name.failed The policy sets this variable in the case of a failure. hmac.HMAC-Policy.failed = true

Example error response

For error handling, the best practice is to trap the errorcode part of the error response. Do not rely on the text in the faultstring, because it could change.

Example fault rule

<FaultRules>
    <FaultRule name="HMAC Policy Errors">
        <Step>
            <Name>AM-Unauthorized</Name>
            <Condition>(fault.name Matches "HmacVerificationFailed")</Condition>
        </Step>
        <Condition>hmac.HMAC-1.failed = true</Condition>
    </FaultRule>
</FaultRules>