Kebijakan HMAC

Halaman ini berlaku untuk Apigee dan Apigee hybrid.

Baca dokumentasi Apigee Edge.

ikon kebijakan

Kebijakan ini menghitung dan memverifikasi Message Authentication Code (HMAC) berbasis Hash secara opsional. Terkadang dikenal sebagai Keyed Message Authentication Code atau Keyed hash, HMAC menggunakan fungsi hash kriptografis seperti SHA-1, SHA-224, SHA-256, SHA-384, SHA-512, atau MD-5, yang diterapkan ke "pesan", bersama dengan kunci rahasia, untuk menghasilkan tanda tangan atau kode autentikasi pesan pada pesan tersebut. Istilah "pesan" di sini mengacu pada aliran byte apa pun. Dalam penggunaan HMAC yang umum, pengirim pesan mengirimkan pesan dan HMAC-nya ke penerima, dan penerima dapat menggunakan HMAC bersama dengan kunci rahasia bersama untuk mengautentikasi pesan.

Kebijakan ini adalah Kebijakan standar dan dapat di-deploy ke jenis lingkungan apa pun. Untuk mengetahui informasi tentang jenis kebijakan dan ketersediaan dengan setiap jenis lingkungan, lihat Jenis kebijakan.

Untuk mempelajari HMAC lebih lanjut, lihat HMAC: Keyed-Hashing for Message Authentication (rfc2104).

Sampel

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

Komputasi tanda tangan dan verifikasi tanda tangan tersebut mengikuti proses yang sama persis. Kebijakan HMAC menghitung HMAC, dan secara opsional dapat memverifikasi tanda tangan yang dihitung terhadap nilai yang diharapkan. Elemen VerificationValue opsional (jika ada) mengarahkan kebijakan untuk memeriksa nilai yang dihitung dengan nilai yang diketahui atau diberikan.


Referensi elemen untuk HMAC

Referensi kebijakan menjelaskan elemen dan atribut kebijakan HMAC.

Atribut yang berlaku untuk elemen tingkat atas

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

Atribut berikut bersifat umum untuk semua elemen induk kebijakan.

Atribut Deskripsi Default Kehadiran
nama Nama internal kebijakan. Karakter yang dapat Anda gunakan dalam nama dibatasi untuk: A-Z0-9._\-$ %. Namun, UI Apigee menerapkan batasan tambahan, seperti menghapus karakter yang bukan alfanumerik secara otomatis.

Secara opsional, gunakan elemen <DisplayName> untuk memberi label pada kebijakan di editor proxy UI Apigee dengan nama bahasa alami yang berbeda.

T/A Wajib
continueOnError Tetapkan ke false untuk menampilkan error saat kebijakan gagal. Perilaku ini wajar terjadi untuk sebagian besar kebijakan.

Tetapkan ke true agar eksekusi alur berlanjut meskipun kebijakan gagal. Lihat juga:

false Opsional
diaktifkan Tetapkan ke true untuk menerapkan kebijakan.

Tetapkan ke false untuk "menonaktifkan" kebijakan. Kebijakan tidak akan diterapkan meskipun tetap terlampir ke alur.

benar Opsional
asinkron Atribut ini tidak digunakan lagi. false Tidak digunakan lagi

<Algorithm>

<Algorithm>algorithm-name</Algorithm>

Menentukan algoritma hash yang akan digunakan saat menghitung HMAC.

Default T/A
Kehadiran Wajib
Jenis String
Nilai yang valid SHA-1, SHA-224, SHA-256, SHA-384, SHA-512, dan MD-5

Konfigurasi kebijakan menerima nama algoritma tanpa membedakan huruf besar dan kecil, serta dengan atau tanpa tanda hubung di antara huruf dan angka. Misalnya, SHA256 dan SHA-256 dan sha256 setara.

<DisplayName>

<DisplayName>Policy Display Name</DisplayName>

Gunakan selain atribut nama untuk memberi label pada kebijakan di editor proxy UI Apigee dengan nama bahasa alami yang berbeda.

Default Jika Anda menghapus elemen ini, nilai atribut nama kebijakan akan digunakan.
Kehadiran Opsional
Jenis String

<Message>

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

Menentukan payload pesan yang akan ditandatangani. Input elemen ini mendukung template pesan (penggantian variabel) untuk memungkinkan item tambahan disertakan saat runtime, seperti stempel waktu, nonce, daftar header, atau informasi lainnya. Contoh:

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

Template pesan dapat menyertakan bagian tetap dan variabel, termasuk baris baru dan fungsi statis. Spasi kosong, seperti baris baru dan karakter spasi, sangat penting.

Default T/A
Kehadiran Wajib
Jenis String
Nilai yang valid String apa pun valid untuk nilai teks. Jika Anda memberikan atribut ref, atribut tersebut akan lebih diutamakan daripada nilai teks. Kebijakan mengevaluasi nilai teks atau variabel yang dirujuk sebagai template pesan.

<Output>

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

Menentukan nama variabel yang harus ditetapkan kebijakan dengan nilai HMAC yang dihitung. Juga menentukan encoding yang akan digunakan untuk output.

Default

Variabel output default-nya adalah hmac.POLICYNAME.output.

Nilai default untuk atribut encoding adalah base64.

Kehadiran Opsional. Jika elemen ini tidak ada, kebijakan akan menetapkan variabel alur hmac.POLICYNAME.output, dengan nilai yang dienkode base64.
Jenis String
Nilai yang valid

Untuk encoding, hex, base16, base64, base64url.

Nilainya tidak peka huruf besar/kecil; hex dan base16 adalah sinonim.

Nilai teks elemen Output dapat berupa nama variabel alur yang valid.

<SecretKey>

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

Menentukan kunci rahasia yang digunakan untuk menghitung HMAC. Kunci diperoleh dari variabel yang dirujuk, yang didekode sesuai dengan encoding tertentu.

Default

Tidak ada nilai default untuk variabel yang direferensikan; atribut ref diperlukan.

Jika tidak ada atribut encoding, kebijakan secara default akan mendekode string kunci rahasia dengan UTF-8 untuk mendapatkan byte kunci.

Kehadiran Wajib
Jenis String
Nilai yang valid

Untuk encoding, nilai yang valid adalah hex, base16, base64, utf8. Setelan defaultnya adalah UTF8. Nilainya tidak peka huruf besar/kecil, dan tanda hubung tidak penting. Base16 sama dengan base-16 dan bAse16. Base16 dan Hex adalah sinonim.

Dengan menggunakan atribut encoding, Anda dapat menentukan kunci yang menyertakan byte di luar rentang karakter yang dapat dicetak UTF-8. Misalnya, konfigurasi kebijakan menyertakan hal berikut:

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

Dan anggap private.encodedsecretkey menyimpan string 536563726574313233.

Dalam hal ini, byte kunci akan didekode sebagai: [53 65 63 72 65 74 31 32 33] (setiap byte direpresentasikan dalam heksadesimal). Sebagai contoh lain, jika menggunakan encoding='base64', dan jika private.encodedsecretkey menyimpan string U2VjcmV0MTIz, hal ini akan menghasilkan kumpulan byte yang sama untuk kunci. Tanpa atribut encoding, atau dengan atribut encoding UTF8, nilai string Secret123 akan menghasilkan kumpulan byte yang sama. Ini menunjukkan tiga cara berbeda untuk merepresentasikan kunci yang sama.

<VerificationValue>

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

(Opsional) Menentukan nilai verifikasi, serta encoding yang digunakan untuk mengenkode nilai verifikasi. Kebijakan akan menggunakan encoding ini untuk mendekode nilai.

Default Tidak ada nilai verifikasi default. Jika elemen ada, tetapi encoding tidak ada, kebijakan akan menggunakan encoding default base64
Kehadiran Opsional
Jenis String
Nilai yang valid

Nilai yang valid untuk atribut encoding adalah: hex, base16, base64, base64url. Nilainya tidak peka huruf besar/kecil; hex dan base16 adalah sinonim.

Encoding VerificationValue tidak harus sama dengan encoding yang digunakan untuk elemen Output.

<IgnoreUnresolvedVariables>

<IgnoreUnresolvedVariables>true|false</IgnoreUnresolvedVariables>

Tetapkan ke false jika Anda ingin kebijakan menampilkan error saat variabel yang dirujuk yang ditentukan dalam kebijakan tidak dapat di-resolve. Tetapkan ke true untuk memperlakukan variabel yang tidak dapat di-resolve sebagai string kosong (null).

Boolean IgnoreUnresolvedVariables hanya memengaruhi variabel yang direferensikan oleh template pesan. Meskipun SecretKey dan VerificationValue dapat mereferensikan variabel, keduanya harus dapat di-resolve, sehingga setelan ignore tidak berlaku untuk keduanya.

Default Salah
Kehadiran Opsional
Jenis Boolean
Nilai yang valid benar atau salah

Variabel alur

Kebijakan dapat menetapkan variabel ini selama eksekusi.

Variabel Deskripsi Contoh
hmac.policy_name.message Kebijakan menetapkan variabel ini dengan pesan yang efektif, hasil evaluasi template pesan yang ditentukan dalam elemen Message. hmac.HMAC-Policy.message = "Hello, World"
hmac.policy_name.output Mendapatkan hasil komputasi HMAC, jika elemen Output tidak menentukan nama variabel. hmac.HMAC-Policy.output = /yyRjydfP+fBHTwXFgc5AZhLAg2kwCri+e35girrGw4=
hmac.policy_name.outputencoding Mendapatkan nama encoding output. hmac.HMAC-Policy.outputencoding = base64

Masalah Umum

Pada satu tingkat, kebijakan HMAC tampaknya sederhana: berikan kunci dan pesan, lalu dapatkan HMAC yang dihitung sebagai respons. Anda mungkin merasa frustrasi saat menggunakan kebijakan ini jika mendapatkan nilai HMAC yang tidak terduga untuk pesan dan kombinasi kunci yang diketahui. Bagian ini akan menjelaskan beberapa catatan penggunaan untuk mengatasi masalah tersebut.

Ada dua masalah umum yang menyebabkan HMAC tidak cocok selama verifikasi: perbedaan spasi kosong dalam pesan, dan perbedaan dalam encoding dan decoding. Yang terakhir berlaku untuk elemen SecretKey serta elemen Output.

Perbedaan Spasi Kosong

Perbedaan yang mungkin tampak tidak penting bagi manusia, memengaruhi nilai HMAC output. Misalnya, kunci rahasia yang dapat direpresentasikan sebagai "Secret123". Dengan decoding UTF-8, byte kunci akan menjadi: [53 65 63 72 65 74 31 32 33]. Menggunakan kunci tersebut untuk menghitung HMAC-SHA256 pada pesan abc akan menghasilkan a7938720fe5749d31076e6961360364c0cd271443f1b580779932c244293bc94. Menambahkan satu spasi ke pesan, sehingga menjadi abc<SPACE>, dengan <SPACE> menyiratkan ASCII 32, menghasilkan HMAC-SHA256 dari 274669b2a85d2532da48e2ce3d8e52ee17346d1bcd1a606d87db1934b5ab294b.

Demikian pula, jika pesannya adalah abc<NEWLINE>, dengan <NEWLINE> menyiratkan ASCII 10, HMAC-nya adalah 0780370844ca07f896066837e8230d3b6a775f678a4ae03e6b5e864c674831f5. Perubahan kecil pada pesan akan menghasilkan nilai HMAC yang sangat berbeda. Hal ini sesuai dengan desain. Ini adalah perilaku HMAC yang diinginkan dan dimaksudkan.

Poin penting: Penting untuk memastikan bahwa isi pesan yang digunakan untuk menghitung HMAC asli dan isi pesan yang digunakan untuk memverifikasi HMAC sama persis. Jika verifier HMAC mengubah payload pesan dengan cara apa pun, dengan menambahkan spasi kosong atau memformat ulang teks, HMAC yang dihitung akan berubah.

Berhati-hatilah saat menggunakan template pesan dalam konfigurasi kebijakan. Misalnya, fragmen konfigurasi kebijakan ini menunjukkan potensi masalah:

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

Hasil evaluasi template pesan dalam elemen <Message> akan menyertakan baris baru dan spasi di sekitar konten pesan. Hal ini mungkin bukan yang dimaksudkan. Konfigurasi yang lebih baik akan terlihat seperti ini:

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

Perbedaan Encoding

Dekode yang berbeda dari materi kunci yang sama, menghasilkan kunci yang berbeda. Misalkan kunci rahasia yang dapat direpresentasikan sebagai "U2VjcmV0S2V5MTIz". Dengan decoding UTF-8, byte kunci seperti yang direpresentasikan dalam base16 akan menjadi: [55 32 56 6a 63 6d 56 30 53 32 56 35 4d 54 49 7a]. Dengan decoding base64, byte kunci akan menjadi [53 65 63 72 65 74 4b 65 79 31 32 33]. Mendekode materi sumber dengan cara yang berbeda akan menghasilkan kunci yang berbeda, dan hal itu akan menghasilkan nilai HMAC yang berbeda.

Poin penting: Penting untuk memastikan bahwa materi kunci yang digunakan untuk menghitung HMAC asli dan kunci yang digunakan untuk memverifikasi HMAC sama persis. Hal ini mungkin berarti memastikan bahwa encoding kunci yang sama digunakan di kedua ujung. Dalam kebijakan HMAC, Anda dapat menggunakan atribut encoding pada elemen SecretKey untuk menentukan encoding kunci.

Pertimbangkan juga encoding pada output. HMAC-SHA256 yang dinyatakan dalam encoding base16 atau hex sebagai 27f17e11c8ece93844c5eb5e55161d993368628a214f9a51c25d0185e8ea06e2 sama dengan HMAC-SHA256 yang dinyatakan dalam bentuk yang dienkode base64 sebagai J/F+Ecjs6ThExeteVRYdmTNoYoohT5pRwl0BhejqBuI=. Keduanya terlihat berbeda, tetapi kedua string ini mewakili nilai yang sama. Pastikan encoding yang sama digunakan untuk mengenkode HMAC yang dihitung awalnya, dan HMAC yang memverifikasi. Dalam kebijakan HMAC, Anda dapat menggunakan atribut encoding pada elemen Output untuk menentukan encoding output yang diinginkan, dan atribut yang sama pada elemen VerificationValue untuk menentukan cara mendekode verifier.

Error reference

This section describes the fault codes and error messages that are returned and fault variables that are set by Apigee when this policy triggers an error. This information is important to know if you are developing fault rules to handle faults. To learn more, see What you need to know about policy errors and Handling faults.

Runtime errors

These errors can occur when the policy executes.

Fault code HTTP status Occurs when
steps.hmac.UnresolvedVariable 401

This error occurs if a variable specified in the HMAC policy is either:

  • Out of scope (not available in the specific flow where the policy is being executed)

    or

  • Can't be resolved (is not defined)
steps.hmac.HmacVerificationFailed 401 The HMAC verification failed; the verification value provided does not match the calculated value.
steps.hmac.HmacCalculationFailed 401 The policy was unable to calculate the HMAC.
steps.hmac.EmptySecretKey 401 The value of the secret key variable is empty.
steps.hmac.EmptyVerificationValue 401 The variable holding the verification value is emtpy.

Deployment errors

These errors can occur when you deploy a proxy containing this policy.

Error name HTTP status Occurs when
steps.hmac.MissingConfigurationElement 401 This error occurs when a required element or attribute is missing.
steps.hmac.InvalidValueForElement 401 This error occurs if the value specified in the Algorithm element is not one of the following values: SHA-1, SHA-224, SHA-256, SHA-512, or MD-5.
steps.hmac.InvalidSecretInConfig 401 This error occurs if there is a text value explicitly provided for SecretKey.
steps.hmac.InvalidVariableName 401 This error occurs if the SecretKey variable does not contain the private prefix (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>