Política de HMAC

Esta página aplica-se ao Apigee e ao Apigee Hybrid.

Veja a documentação do Apigee Edge.

Ícone de política

Esta política calcula e, opcionalmente, valida um código de autenticação de mensagens baseado numa função hash (HMAC). Por vezes 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", juntamente com uma chave secreta, para produzir uma assinatura ou um código de autenticação de mensagens nessa mensagem. O termo "mensagem" aqui refere-se a qualquer fluxo de bytes. Na utilização típica do HMAC, um remetente de uma mensagem envia uma mensagem e o respetivo HMAC a um destinatário, e o destinatário pode utilizar o HMAC juntamente com a chave secreta partilhada para autenticar a mensagem.

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

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

Amostras

Gere 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>

Valide o 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>

O cálculo de uma assinatura e a validação dessa assinatura seguem exatamente o mesmo processo. A política HMAC calcula um HMAC e, opcionalmente, pode validar a assinatura calculada em relação a 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 elemento para HMAC

A referência da política descreve os elementos e os atributos da política de 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 principais da política.

Atributo Descrição Predefinição Presença
nome O nome interno da política. Os carateres que pode usar no nome estão restritos a: A-Z0-9._\-$ %. No entanto, a IU do Apigee aplica restrições adicionais, como a remoção automática de carateres que não sejam alfanuméricos.

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

N/A Obrigatória
continueOnError Definido como false para devolver um erro quando uma política falha. Este comportamento é o esperado para a maioria das políticas.

Definido como true para que a execução do fluxo continue mesmo após a falha de uma política. Veja também:

falso Opcional
ativada Defina como true para aplicar a política.

Defina como false para "desativar" a política. A política não é aplicada, mesmo que permaneça associada a um fluxo.

verdadeiro Opcional
assíncrono Este atributo foi descontinuado. falso Descontinuado

<Algorithm>

<Algorithm>algorithm-name</Algorithm>

Especifica o algoritmo hash a usar ao calcular o HMAC.

Predefinição N/A
Presença Obrigatória
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 algoritmos sem distinguir maiúsculas de minúsculas e com ou sem o traço entre as letras e os números. Por exemplo, SHA256, SHA-256 e sha256 são equivalentes.

<DisplayName>

<DisplayName>Policy Display Name</DisplayName>

Use em conjunto com o atributo name para etiquetar a política no editor de proxy da IU do Apigee com um nome diferente em linguagem natural.

Predefinição Se omitir este elemento, é usado o valor do atributo name da política.
Presença Opcional
Tipo String

<Message>

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

Especifica a carga útil da mensagem a assinar. A entrada deste elemento suporta modelos de mensagens (substituição de variáveis) para permitir a inclusão de itens adicionais no tempo de execução, como indicações de tempo, números únicos, listas de cabeçalhos ou outras informações. Por 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. Os espaços em branco, como quebras de linha e carateres de espaço, são significativos.

Predefinição N/A
Presença Obrigatória
Tipo String
Valores válidos Qualquer cadeia é válida para o valor de texto. Se fornecer um atributo ref, este tem prioridade sobre o valor de texto. A política avalia o valor de 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 deve definir com o valor HMAC calculado. Também especifica a codificação a usar para o resultado.

Predefinição

A variável de saída predefinida é hmac.POLICYNAME.output.

O valor predefinido do atributo encoding é base64.

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

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

Os valores não são sensíveis a maiúsculas e minúsculas; 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 a partir da variável referenciada e descodificada de acordo com a codificação específica.

Predefinição

Não existe um valor predefinido para a variável referenciada; o atributo ref é obrigatório.

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

Presença Obrigatória
Tipo String
Valores válidos

Para encoding, os valores válidos são hex, base16, base64 e utf8. A predefinição é UTF8. Os valores não são sensíveis a maiúsculas e minúsculas, e os travessões são insignificantes. Base16 é o mesmo que base-16 e bAse16. Base16 e Hex são sinónimos.

A utilização de um atributo de codificação permite-lhe especificar uma chave que inclui bytes fora do intervalo de carateres imprimíveis UTF-8. Por exemplo, suponhamos que a configuração da política inclui o seguinte:

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

Suponhamos que private.encodedsecretkey contém a string 536563726574313233.

Neste caso, os bytes da chave são descodificados como: [53 65 63 72 65 74 31 32 33] (cada byte representado em hexadecimal). Como outro exemplo, se usar encoding='base64', e se private.encodedsecretkey contiver a string U2VjcmV0MTIz, resulta no mesmo conjunto de bytes para a chave. Sem um atributo de codificação ou com um atributo de codificação de UTF8, o valor de string Secret123 resultaria no mesmo conjunto de bytes. Isto mostra três formas diferentes de representar a mesma tecla.

<VerificationValue>

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

(Opcional) Especifica o valor de validação, bem como a codificação que foi usada para codificar o valor de validação. A política vai usar esta codificação para descodificar o valor.

Predefinição Não existe um valor de validação predefinido. Se o elemento estiver presente, mas o atributo encoding estiver ausente, a política usa uma codificação predefinida de base64
Presença Opcional
Tipo String
Valores válidos

Os valores válidos para o atributo de codificação são: hex, base16, base64, base64url. Os valores não são sensíveis a maiúsculas e minúsculas; hex e base16 são sinónimos.

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

<IgnoreUnresolvedVariables>

<IgnoreUnresolvedVariables>true|false</IgnoreUnresolvedVariables>

Defina como false se quiser que a política apresente 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 resolvível como uma string vazia (nula).

O booleano IgnoreUnresolvedVariables afeta apenas as variáveis referenciadas pelo modelo de mensagem. Embora SecretKey e VerificationValue possam referenciar uma variável, ambas têm de ser resolvíveis, pelo que a definição ignore não se aplica a estas.

Predefinição Falso
Presença Opcional
Tipo Booleano
Valores válidos verdadeiro ou falso

Variáveis de fluxo

A política pode definir estas variáveis durante a execução.

Variável Descrição Exemplo
hmac.policy_name.message A política define esta variável com a mensagem eficaz, o resultado da avaliação do modelo de mensagem especificado no elemento Message. hmac.HMAC-Policy.message = "Hello, World"
hmac.policy_name.output Obtém 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 Obtém o nome da codificação de saída. hmac.HMAC-Policy.outputencoding = base64

Problemas comuns

A um nível, a política de HMAC parece ser simples: forneça uma chave e uma mensagem e receba um HMAC calculado em resposta. Pode ser frustrante usar a política se obtiver um valor HMAC inesperado para uma combinação de mensagem e chave conhecida. Esta secção explica algumas notas de utilização para resolver esses problemas.

Existem duas armadilhas comuns que resultam em HMACs não correspondentes durante a validação: diferenças de espaços em branco na mensagem e diferenças na codificação e descodificação. O último aplica-se ao elemento SecretKey, bem como ao elemento Output.

Diferenças de espaços em branco

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

Da mesma forma, se a mensagem for abc<NEWLINE>, em que <NEWLINE> implica um ASCII 10, o HMAC é 0780370844ca07f896066837e8230d3b6a775f678a4ae03e6b5e864c674831f5. Pequenas alterações na mensagem resultam em valores HMAC muito diferentes. Isto é intencional. Este é um comportamento pretendido e desejado do HMAC.

Conclusão: é importante garantir que o corpo da mensagem usado para calcular o HMAC original e o corpo da mensagem usado para validar o HMAC são exatamente iguais. Se o validador de um HMAC alterar o payload da mensagem de alguma forma, adicionando espaços em branco ou reformatando o texto, o HMAC calculado é alterado.

Tenha especial cuidado ao usar um modelo de mensagem na configuração de políticas. Por exemplo, este fragmento de configuração de política mostra um potencial 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> inclui novas linhas e espaços em torno do conteúdo da mensagem. Isto provavelmente não é o pretendido. Uma melhor configuração teria o seguinte aspeto:

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

Diferenças na codificação

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

Conclusão: é importante garantir que o material da chave usado para calcular o HMAC original e a chave usada para validar o HMAC são exatamente iguais. Isto significa provavelmente que deve garantir que a mesma codificação da chave é usada em ambas as extremidades. Na política HMAC, pode 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 é o mesmo que um HMAC-SHA256 expresso na forma codificada em base64 como J/F+Ecjs6ThExeteVRYdmTNoYoohT5pRwl0BhejqBuI=. Embora tenham um aspeto diferente, estas duas strings representam o mesmo valor. Certifique-se de que a mesma codificação é usada para codificar o HMAC calculado originalmente e o HMAC de validação. Na política de HMAC, pode usar o atributo encoding no Outputelemento para especificar a codificação de saída pretendida e o mesmo atributo no VerificationValueelemento para especificar como descodificar o validador.

Referência de erro

Esta secção descreve os códigos de falha e as mensagens de erro devolvidas, bem como as variáveis de falha definidas pelo Apigee quando esta política aciona um erro. Estas informações são importantes para saber se está a desenvolver regras de falhas para tratar falhas. Para saber mais, consulte o artigo O que precisa de saber acerca dos erros de políticas e o artigo Processamento de falhas.

Erros de tempo de execução

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

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

Este erro ocorre se uma variável especificada na política de HMAC:

  • Fora do âmbito (não disponível no fluxo específico onde a política está a ser executada)

    ou

  • Não é possível resolver (não está definido)
steps.hmac.HmacVerificationFailed 401 Falha na validação de HMAC. O valor de validaçã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 validação está vazia.

Erros de implementação

Estes erros podem ocorrer quando implementa um proxy que contém esta política.

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

Variáveis de falha

Estas variáveis são definidas quando ocorre um erro de tempo de execução. Para mais informações, consulte o artigo O que precisa de saber acerca dos erros de políticas.

Variáveis Onde Exemplo
fault.name="fault_name" fault_name é o nome da falha, conforme indicado na tabela Erros de tempo de execução acima. O nome da falha é a última parte do código de falha. fault.name Matches "UnresolvedVariable"
hmac.policy_name.failed A política define esta variável em caso de falha. hmac.HMAC-Policy.failed = true

Exemplo de resposta de erro

Para o processamento de erros, a prática recomendada é captar a parte errorcode da resposta de erro. Não confie no texto em faultstring, porque pode mudar.

Exemplo de regra de falha

<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>