HMAC-Richtlinie

Diese Seite gilt für Apigee und Apigee Hybrid.

Apigee Edge-Dokumentation aufrufen

Richtliniensymbol

Diese Richtlinie berechnet und verifiziert optional einen Hash-basierten Nachrichtenauthentifizierungscode (Hash-based Message Authentication Code, HMAC). HMAC wird manchmal auch als Keyed Message Authentication Code oder Keyed Hash bezeichnet und verwendet eine kryptografische Hash-Funktion wie SHA-1, SHA-224, SHA-256, SHA-384, SHA-512 oder MD-5, die zusammen mit einem geheimen Schlüssel auf eine "Nachricht" angewendet wird, um eine Signatur oder Nachrichtenauthentifizierungscode für diese Nachricht zu erstellen. Der Begriff "Nachricht" bezieht sich hier auf beliebige Byte-Streams. Bei der typischen Verwendung von HMAC sendet der Absender einer Nachricht eine Nachricht und den zugehörigen HMAC an einen Empfänger. Der Empfänger kann den HMAC zusammen mit dem gemeinsamen geheimen Schlüssel zur Authentifizierung der Nachricht verwenden.

Diese Richtlinie ist eine Standardrichtlinie und kann in jedem Umgebungstyp bereitgestellt werden. Nicht alle Nutzer müssen Richtlinien- und Umgebungstypen kennen. Informationen zu Richtlinientypen und zur Verfügbarkeit bei jedem Umgebungstyp finden Sie unter Richtlinientypen.

Weitere Informationen zu HMAC finden Sie unter HMAC: Keyed-Hashing for Message Authentication (rfc2104).

Beispiele

HMAC generieren

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

HMAC überprüfen

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

Die Berechnung einer Signatur und die Überprüfung dieser Signatur folgen genau dem gleichen Vorgang. Die HMAC-Richtlinie berechnet einen HMAC und kann optional die berechnete Signatur mit einem erwarteten Wert abgleichen. Das optionale Element VerificationValue (falls vorhanden) weist die Richtlinie an, den berechneten Wert mit einem bekannten oder gegebenen Wert zu vergleichen.


Elementreferenz für HMAC

In der Richtlinienreferenz werden die Elemente und Attribute der HMAC-Richtlinie beschrieben.

Attribute, die auf das oberste Element angewendet werden

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

Die folgenden Attribute gelten für alle übergeordneten Richtlinienelemente.

Attribut Beschreibung Standard Präsenz
name Der interne Name der Richtlinie. Folgende Zeichen sind im Namen zulässig: A-Z0-9._\-$ %. Die Apigee-Benutzeroberfläche erzwingt jedoch zusätzliche Einschränkungen, z. B. das automatische Entfernen nicht alphanumerischer Zeichen.

Optional können Sie das Element <DisplayName> verwenden, um die Richtlinie im Proxy-Editor der Apigee-Benutzeroberfläche mit einem anderen Namen in der natürlichen Sprache zu versehen.

Erforderlich
continueOnError Legen Sie false fest, um einen Fehler zurückzugeben, wenn eine Richtlinie fehlschlägt. Dies ist für die meisten Richtlinien das erwartete Verhalten.

Legen Sie true fest, damit die Ablaufausführung auch nach dem Fehlschlagen einer Richtlinie fortgesetzt wird. Weitere Informationen

falsch Optional
Aktiviert Legen Sie true fest, um die Richtlinie zu erzwingen.

Legen Sie false fest, um die Richtlinie zu "deaktivieren". Die Richtlinie wird nicht erzwungen, selbst wenn sie mit einem Ablauf verknüpft ist.

true Optional
async Dieses Attribut wurde verworfen. false Veraltet

<Algorithm>

<Algorithm>algorithm-name</Algorithm>

Gibt den Hash-Algorithmus an, der beim Berechnen des HMAC verwendet werden soll.

Standard
Präsenz Erforderlich
Typ String
Zulässige Werte SHA-1, SHA-224, SHA-256, SHA-384, SHA-512, und MD-5

Die Richtlinienkonfiguration akzeptiert Algorithmusnamen, ohne zwischen Groß- und Kleinschreibung zu unterscheiden, und mit oder ohne den Bindestrich zwischen Buchstaben und Zahlen. Beispiel: SHA256 und SHA-256 und sha256 sind äquivalent.

<DisplayName>

<DisplayName>Policy Display Name</DisplayName>

Wird zusätzlich zum Namensattribut verwendet, um die Richtlinie im Proxy-Editor der Apigee-Benutzeroberfläche mit einem anderen Namen in einer natürlichen Sprache zu versehen.

Standard Wenn Sie dieses Element weglassen, wird der Wert des Namensattributs der Richtlinie verwendet.
Präsenz Optional
Typ String

<Message>

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

Gibt die zu signierende Nachrichtennutzlast an. Die Eingabe dieses Elements unterstützt Nachrichtenvorlagen (Variablensubstitution), damit zusätzliche Elemente zur Laufzeit einbezogen werden können, z. B. Zeitstempel, Nonces, Listen von Headern oder andere Informationen. Beispiel:

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

Die Nachrichtenvorlage kann feste und variable Teile enthalten, einschließlich Zeilenumbrüchen und statischer Funktionen. Leerstellen wie Zeilenumbrüche und Leerzeichen sind wichtig.

Standard
Präsenz Erforderlich
Typ String
Zulässige Werte Jeder String ist für den Textwert gültig. Wenn Sie ein ref-Attribut angeben, hat es Vorrang vor dem Textwert. Die Richtlinie wertet entweder den Textwert oder die referenzierte Variable als Nachrichtenvorlage aus.

<Output>

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

Gibt den Namen der Variable an, die die Richtlinie mit dem berechneten HMAC-Wert festlegen soll. Außerdem wird die für die Ausgabe zu verwendende Codierung angegeben.

Standard

Die Standardausgabevariable ist hmac.POLICYNAME.output.

Der Standardwert für das Attribut encoding ist base64.

Präsenz Optional. Wenn dieses Element nicht vorhanden ist, legt die Richtlinie die Ablaufvariable hmac.POLICYNAME.output mit einem base64-codierten Wert fest.
Typ String
Zulässige Werte

Zum Codieren von hex, base16, base64, base64url.

Bei den Werten wird die Groß-/Kleinschreibung nicht berücksichtigt; hex und base16 sind Synonyme.

Der Textwert des Output-Elements kann ein beliebiger gültiger Name der Ablaufvariablen sein.

<SecretKey>

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

Gibt den geheimen Schlüssel an, der zur Berechnung des HMAC verwendet wird. Der Schlüssel wird gemäß der spezifischen Codierung aus der referenzierten Variable abgerufen.

Standard

Für die referenzierte Variable gibt es keinen Standardwert. Das Attribut ref ist erforderlich.

Wenn kein encoding-Attribut vorhanden ist, decodiert die Richtlinie den geheimen Schlüsselstring standardmäßig mit UTF-8, um die Schlüsselbyte zu erhalten.

Präsenz Erforderlich
Typ String
Zulässige Werte

Gültige Werte für encoding sind hex, base16, base64 und utf8. Der Standard ist UTF-8. Bei den Werten wird die Groß-/Kleinschreibung nicht berücksichtigt. Bindestriche sind nicht wichtig. Base16 ist mit base-16 und bAse16 identisch. Base16 und Hex sind Synonyme.

Mit einem Codierungsattribut können Sie einen Schlüssel angeben, der Byte außerhalb des Bereichs der für UTF-8 druckbaren Zeichen enthält. Angenommen, die Richtlinienkonfiguration enthält Folgendes:


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

Und angenommen, private.encodedsecretkey enthält den String 536563726574313233.

In diesem Fall werden die Schlüsselbyte folgendermaßen decodiert: [53 65 63 72 65 65 74 31 32 33] (jedes Byte wird als Hexadezimalwert dargestellt). Ein weiteres Beispiel: Wenn Sie encoding='base64' verwenden und private.encodedsecretkey den String U2VjcmV0MTIz enthält, wird der gleiche Satz Byte für den Schlüssel ausgegeben. Ohne Codierungsattribut oder mit dem Codierungsattribut UTF8 führt der Stringwert Secret123 zum selben Satz Byte. Hier werden drei verschiedene Möglichkeiten zur Darstellung desselben Schlüssel gezeigt.

<VerificationValue>

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

(Optional) Gibt den Überprüfungswert sowie die Codierung an, die zum Codieren des Überprüfungswerts verwendet wurde. Die Richtlinie verwendet diese Codierung, um den Wert zu decodieren.

Standard Es gibt keinen Standardwert für die Bestätigung. Wenn das Element vorhanden ist, das Attribut encoding jedoch fehlt, verwendet die Richtlinie die Standardcodierung base64.
Präsenz Optional
Typ String
Zulässige Werte

Gültige Werte für das Codierungsattribut sind hex, base16, base64, base64url. Bei den Werten wird die Groß-/Kleinschreibung nicht berücksichtigt; hex und base16 sind Synonyme.

Die Codierung von VerificationValue muss nicht der Codierung entsprechen, die für das Element Output verwendet wird.

<IgnoreUnresolvedVariables>

<IgnoreUnresolvedVariables>true|false</IgnoreUnresolvedVariables>

Setzen Sie diesen Wert auf false, wenn die Richtlinie einen Fehler ausgibt, falls eine in der Richtlinie angegebene Variable, auf die verwiesen wird, nicht auflösbar ist. Setzen Sie diesen Wert auf true, um alle nicht aufgelösten Variablen als leeren String zu behandeln (null).

Der boolesche Wert "IgnoreUnresolvedVariables betrifft nur Variablen, auf die in der Nachrichtenvorlage verwiesen wird. Obwohl SecretKey und VerificationValue auf eine Variable verweisen können, müssen beide aufgelöst werden können. Daher gilt die Einstellung ignore nicht für diese.

Standard False
Präsenz Optional
Typ Boolean
Zulässige Werte "true" oder "false"

Ablaufvariablen

Die Richtlinie kann diese Variablen während der Ausführung festlegen.

Variable Beschreibung Beispiel
hmac.policy_name.message Die Richtlinie legt diese Variable mit der effektiven Nachricht fest, das Ergebnis der Auswertung der im Element Message angegebenen Nachrichtenvorlage. hmac.HMAC-Policy.message = "Hello, World"
hmac.policy_name.output Ruft das Ergebnis der HMAC-Berechnung ab, wenn das Output-Element keinen Variablennamen angibt. hmac.HMAC-Policy.output = /yyRjydfP+fBHTwXFgc5AZhLAg2kwCri+e35girrGw4=
hmac.policy_name.outputencoding Ruft den Namen der Ausgabecodierung ab. hmac.HMAC-Policy.outputencoding = base64

Allgemeine Probleme

Auf einer Ebene scheint die HMAC-Richtlinie unkompliziert zu sein: Geben Sie einen Schlüssel und eine Nachricht an und Sie erhalten einen berechneten HMAC als Antwort. Es kann frustrierend sein, wenn Sie bei Verwendung der Richtlinie einen unerwarteten HMAC-Wert für eine bekannte Kombination aus Nachricht und Schlüssel erhalten. In diesem Abschnitt werden einige Nutzungshinweise zur Behebung solcher Probleme erläutert.

Es gibt zwei übliche Stolperfallen, die während der Prüfung zu nicht übereinstimmenden HMACs führen: Unterschiede bei Leerstellen in der Nachricht und Unterschiede bei Codierung und Decodierung. Letzteres gilt sowohl für das SecretKey-Element als auch für das Output-Element.

Unterschiede bei Leerzeichen

Unterschiede, die für Menschen bedeutungslos wirken, wirken sich auf den HMAC-Ausgabewert aus. Angenommen, ein geheimer Schlüssel kann als "Secret123“ dargestellt werden. Bei der UTF-8-Decodierung lauten die Schlüsselbyte: [53 65 63 72 65 74 31 32 33]. Die Verwendung dieses Schlüssels zum Berechnen eines HMAC-SHA256 für die Nachricht abc führt zu a7938720fe5749d31076e6961360364c0cd271443f1b580779932c244293bc94. Wenn Sie der Nachricht ein einzelnes Leerzeichen (abc<SPACE>) hinzufügen, wobei <SPACE> ein ASCII 32 impliziert, führt dies zu einem HMAC-SHA256 von 274669b2a85d2532da48e2ce3d8e52ee17346d1bcd1a606d87db1934b5ab294b.

Ist die Nachricht abc<NEWLINE>, wobei <NEWLINE> auf ASCII 10 verweist, ist der HMAC ebenfalls 0780370844ca07f896066837e8230d3b6a775f678a4ae03e6b5e864c674831f5. Geringfügige Änderungen an der Nachricht führen zu sehr unterschiedlichen HMAC-Werten. Dies geschieht absichtlich. Dies ist ein beabsichtigtes und gewünschtes Verhalten von HMAC.

Fazit: Es muss unbedingt dafür gesorgt werden, dass der Nachrichtentext, der zur Berechnung des ursprünglichen HMAC verwendet wird, und der Nachrichtentext, der zur Überprüfung des HMAC verwendet wird, identisch sind. Wenn der Verifizierer eines HMAC die Nachrichtennutzlast in irgendeiner Weise ändert, beispielsweise durch Hinzufügen eines Leerzeichens oder Neuformatieren von Text, ändert sich der berechnete HMAC.

Seien Sie besonders vorsichtig, wenn Sie eine Nachrichtenvorlage in der Richtlinienkonfiguration verwenden. Dieses Richtlinienkonfigurationsfragment zeigt beispielsweise ein potenzielles Problem:

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

</HMAC>

Bei einer Auswertung der Nachrichtenvorlage innerhalb des <Message>-Elements wird der Nachrichteninhalt in Zeilenumbrüche und Leerzeichen eingeschlossen. Dies ist wahrscheinlich nicht beabsichtigt. Eine bessere Konfiguration würde so aussehen:

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

</HMAC>

Unterschiede bei der Codierung

Unterschiedliche Decodierungen desselben Schlüsselmaterials führen zu unterschiedlichen Schlüsseln. Angenommen, Sie haben einen geheimen Schlüssel, der als "U2VjcmV0S2V5MTIz" dargestellt werden kann. Bei der UTF-8-Decodierung lauten die Schlüsselbyte, wie in base16 dargestellt: [55 32 56 6a 63 6d 56 30 53 32 56 35 4d 54 49 7a]. Bei der base64-Decodierung lauten die Schlüsselbyte [53 65 63 72 65 74 4b 65 79 31 32 33]. Das Decodieren des Quellmaterials führt zu unterschiedlichen Schlüsseln, was zu unterschiedlichen HMAC-Werten führt.

Hierbei gilt: Es muss unbedingt sichergestellt werden, dass das Schlüsselmaterial, das zur Berechnung des ursprünglichen HMAC verwendet wird, und der Schlüssel, der zum Prüfen des HMAC verwendet wird, genau identisch sind. Das bedeutet wahrscheinlich, dass an beiden Enden dieselbe Codierung des Schlüssels verwendet wird. In der HMAC-Richtlinie können Sie das encoding-Attribut für das SecretKey-Element verwenden, um die Schlüsselcodierung anzugeben.

Berücksichtigen Sie auch Codierungen in der Ausgabe. Ein HMAC-SHA256-Ausdruck in der base16- oder Hex-Codierung in Form von 27f17e11c8ece93844c5eb5e55161d993368628a214f9a51c25d0185e8ea06e2 ist mit einem HMAC-SHA256 identisch, in base64-Codierung als J/F+Ecjs6ThExeteVRYdmTNoYoohT5pRwl0BhejqBuI= ausgedrückt. Sie sehen unterschiedlich aus, aber diese beiden Strings stehen für denselben Wert. Achten Sie darauf, dass dieselbe Codierung verwendet wird, um den ursprünglich berechneten HMAC und den überprüfenden HMAC zu codieren. In der HMAC-Richtlinie können Sie das Attribut encoding für das Output-Element verwenden, um die gewünschte Ausgabecodierung und das gleiche Attribut für das VerificationValue-Element anzugeben, um anzugeben, wie der Verifizierer decodiert werden soll.

Fehlerreferenz

In diesem Abschnitt werden die zurückgegebenen Fehlercodes und Fehlermeldungen beschrieben, die von Apigee festgelegt werden, wenn die Richtlinie einen Fehler auslöst. Diese Informationen sind wichtig, wenn Sie Fehlerregeln zur Verarbeitung von Fehlern entwickeln. Weitere Informationen finden Sie unter Was Sie über Richtlinienfehler wissen müssen und Fehler beheben.

Laufzeitfehler

Diese Fehler können bei Ausführung der Richtlinie auftreten.

Fehlercode HTTP-Status Tritt auf, wenn Folgendes eintritt
steps.hmac.UnresolvedVariable 401

Dieser Fehler tritt auf, wenn für eine in der HMAC-Richtlinie angegebenen Variablen Folgendes gilt:

  • Wert liegt außerhalb des Bereichs (nicht in dem spezifischen Ablauf verfügbar, in dem die Richtlinie ausgeführt wird)

    oder

  • kann nicht gelöst werden (ist nicht definiert)
steps.hmac.HmacVerificationFailed 401 Die HMAC-Verifizierung ist fehlgeschlagen. Der bereitgestellte Verifizierungswert stimmt nicht mit dem berechneten Wert überein.
steps.hmac.HmacCalculationFailed 401 Der HMAC-Wert konnte mit der Richtlinie nicht berechnet werden.
steps.hmac.EmptySecretKey 401 Der Wert der geheimen Schlüsselvariablen ist leer.
steps.hmac.EmptyVerificationValue 401 Die Variable, die den Verifizierungswert enthält, ist leer.

Bereitstellungsfehler

Diese Fehler können auftreten, wenn Sie einen Proxy mit dieser Richtlinie bereitstellen.

Fehlername HTTP-Status Tritt auf, wenn Folgendes eintritt
steps.hmac.MissingConfigurationElement 401 Dieser Fehler tritt auf, wenn ein erforderliches Element oder Attribut fehlt.
steps.hmac.InvalidValueForElement 401 Dieser Fehler tritt auf, wenn der im Algorithmuselement angegebene Wert keiner der folgenden ist: SHA-1, SHA-224, SHA-256, SHA-512 oder MD-5.
steps.hmac.InvalidSecretInConfig 401 Dieser Fehler tritt auf, wenn ein expliziter Textwert für SecretKey angegeben wird.
steps.hmac.InvalidVariableName 401 Dieser Fehler tritt auf, wenn die Variable SecretKey nicht das Präfix private (private.) enthält.

Fehlervariablen

Diese Variablen werden bei Laufzeitfehlern festgelegt. Weitere Informationen finden Sie unter Was Sie über Richtlinienfehler wissen müssen.

Variablen Wo Beispiel
fault.name="fault_name" fault_name ist der Name des Fehlers, der in der obigen Tabelle Laufzeitfehler aufgeführt ist. Der Fehlername ist der letzte Teil des Fehlercodes. fault.name Matches "UnresolvedVariable"
hmac.policy_name.failed Bei einem Fehler legt die Richtlinie diese Variable fest. hmac.HMAC-Policy.failed = true

Beispiel für eine Fehlerantwort

Bei der Fehlerbehandlung besteht die Best Practice darin, den errorcode-Teil der Fehlerantwort zu beachten. Verlassen Sie sich nicht auf den Text in faultstring. Er kann sich ändern.

Beispiel für eine Fehlerregel

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