이 페이지는 Apigee 및 Apigee Hybrid에 적용됩니다.
Apigee Edge 문서 보기
이 정책은 해시 기반 메시지 인증 코드(HMAC)를 계산하고 선택적으로 확인합니다. 간혹 키 메시지 인증 코드 또는 키 해시라고도 하는 HMAC는 보안 비밀 키와 함께 사용하여 '메시지'에 적용된 SHA-1, SHA-224, SHA-256, SHA-384, SHA-512 또는 MD-5와 같은 암호화 해시 함수를 사용하여 해당 메시지에 서명 또는 메시지 인증 코드를 생성합니다. 여기서 '메시지'라는 용어는 모든 바이트 스트림을 의미합니다. HMAC의 일반적인 사용 사례에서 메시지 발신자는 메시지 및 HMAC를 수신자에게 전송하고 수신자는 공유 비밀번호 키와 함께 HMAC를 사용하여 메시지를 인증할 수 있습니다.
이 정책은 표준 정책이며 모든 환경 유형에 배포할 수 있습니다. 정책 유형과 각 환경 유형에서의 가용성에 대한 자세한 내용은 정책 유형을 참조하세요.
HMAC에 대한 자세한 내용은 HMAC: Keyed-Hashing for Message Authentication (rfc2104)을 참조하세요.
샘플
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>
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>
서명 계산과 서명 확인은 완전히 같은 프로세스를 따릅니다. HMAC 정책은 HMAC를 계산하고, 계산된 서명을 예상 값에 대해 선택적으로 확인할 수 있습니다. 선택사항인 VerificationValue
요소(있는 경우)는 계산된 값을 알려진 값 또는 지정된 값과 대조하도록 정책에 지시합니다.
HMAC의 요소 참조
정책 참조는 HMAC 정책의 요소 및 속성을 설명합니다.
최상위 요소에 적용되는 속성
<HMAC name="HMAC" continueOnError="false" enabled="true" async="false">
다음 속성은 모든 정책 상위 요소에 공통적으로 적용됩니다.
속성 | 설명 | 기본값 | Presence |
---|---|---|---|
이름 |
정책의 내부 이름입니다. 이름에 사용할 수 있는 문자는 A-Z0-9._\-$ % 로 제한됩니다. 그러나 Apigee UI는 영숫자가 아닌 문자를 자동으로 삭제하는 등 추가 제한사항을 적용합니다.
선택적으로 |
해당 사항 없음 | 필수 |
continueOnError |
정책이 실패할 경우 오류가 반환되도록 하려면 false 로 설정합니다. 이는 대부분의 정책에서 예상되는 동작입니다.
정책이 실패해도 흐름 실행이 계속되도록 하려면 |
false | 선택사항 |
사용 설정됨 | 정책을 시행하려면 true 로 설정합니다.
|
true | 선택사항 |
async | 이 속성은 지원이 중단되었습니다. | false | 지원 중단됨 |
<Algorithm>
<Algorithm>algorithm-name</Algorithm>
HMAC를 계산할 때 사용할 해시 알고리즘을 지정합니다.
기본값 | 해당 사항 없음 |
Presence | 필수 |
유형 | 문자열 |
유효한 값 | SHA-1 , SHA-224 , SHA-256 , SHA-384 ,
SHA-512 , MD-5
정책 구성은 대소문자를 구분하지 않고 문자와 숫자 사이에 대시를 포함하거나 포함하지 않는 알고리즘 이름을 허용합니다. 예를 들어 |
<DisplayName>
<DisplayName>Policy Display Name</DisplayName>
이름 속성 외에도 이 요소를 사용하여 Apigee UI 프록시 편집기의 정책에 다른 자연어 이름으로 라벨을 지정합니다.
기본값 | 이 요소를 생략하면 정책 이름 속성 값이 사용됩니다. |
Presence | 선택사항 |
유형 | 문자열 |
<Message>
<Message>message_template_here</Message> or <Message ref='variable_here'/>
서명할 메시지 페이로드를 지정합니다. 이 요소의 입력은 메시지 템플릿(변수 대체)을 지원하므로 타임스탬프, nonce, 헤더 목록 또는 기타 정보와 같은 추가 항목을 런타임에 포함할 수 있습니다. 예를 들면 다음과 같습니다.
<Message>Fixed Part {a_variable} {timeFormatUTCMs(timeFormatString1,system.timestamp)} {nonce} </Message>
메시지 템플릿은 줄바꿈 및 정적 함수를 포함하여 고정 및 가변 부분을 포함할 수 있습니다. 줄바꿈 및 공백 문자와 같은 공백은 중요합니다.
기본값 | 해당 사항 없음 |
Presence | 필수 |
유형 | 문자열 |
유효한 값 | 텍스트 값에 모든 문자열은 유효합니다. ref 속성을 제공하면 텍스트 값보다 우선합니다. 정책은 텍스트 값 또는 참조된 변수를 메시지 템플릿으로 평가합니다. |
<Output>
<Output encoding='encoding_name'>variable_name</Output>
계산된 HMAC 값으로 정책을 설정해야 하는 변수의 이름을 지정합니다. 또한 출력에 사용할 인코딩을 지정합니다.
기본값 |
기본 출력 변수는 |
Presence | 선택사항입니다. 이 요소가 없으면 정책은 base64로 인코딩된 값을 사용하여 흐름 변수 hmac.POLICYNAME.output 을 설정합니다. |
유형 | 문자열 |
유효한 값 | 인코딩의 경우 값은 대소문자를 구분하지 않고,
|
<SecretKey>
<SecretKey encoding='encoding_name' ref='private.secretkey'/>
HMAC를 계산하는 데 사용되는 보안 비밀번호 키를 지정합니다. 키는 구체적인 인코딩에서 디코딩된 참조된 변수에서 가져옵니다.
기본값 |
참조된 변수에는 기본값이 없으며
|
Presence | 필수 |
유형 | 문자열 |
유효한 값 |
인코딩 속성을 사용하면 UTF-8 인쇄 가능 문자 범위를 벗어난 바이트가 포함된 키를 지정할 수 있습니다. 예를 들어 정책 구성에 다음이 포함되어 있다고 가정해 보겠습니다. <SecretKey encoding='hex' ref='private.encodedsecretkey'/>
그리고
이 경우 키 바이트는 [53 65 63 72 65 74 31 32 33]으로 디코딩됩니다(각 바이트는 16진수로 표시됨). 또 다른 예시로 |
<VerificationValue>
<VerificationValue encoding='encoding_name' ref='variable_name'/> or <VerificationValue encoding='encoding_name'>string_value</VerificationValue>
(선택사항) 확인 값과 확인 값을 인코딩하는 데 사용된 인코딩을 지정합니다. 정책에서 이 인코딩을 사용하여 값을 디코딩합니다.
기본값 | 기본 확인 값이 없습니다. 요소가 있지만 encoding 속성이 없으면 정책은 base64 의 기본 인코딩을 사용합니다. |
Presence | 선택사항 |
유형 | 문자열 |
유효한 값 |
인코딩 속성의 유효한 값은
|
<IgnoreUnresolvedVariables>
<IgnoreUnresolvedVariables>true|false</IgnoreUnresolvedVariables>
정책에 지정된 참조 변수를 해결할 수 없는 경우 정책에서 오류가 발생하게 하려면 false
로 설정합니다. 해결할 수 없는 변수를 빈 문자열(null)로 취급하려면 true
로 설정합니다.
IgnoreUnresolvedVariables 부울은 메시지 템플릿이 참조하는 변수에만 영향을 줍니다. SecretKey
및 VerificationValue
는 변수를 참조할 수 있지만 둘 다 확인할 수 있어야 하므로 ignore
설정이 적용되지 않습니다.
기본값 | 거짓 |
Presence | 선택사항 |
유형 | 불리언 |
유효한 값 | true 또는 false |
흐름 변수
정책은 실행 중에 이러한 변수를 설정할 수 있습니다.
변수 | 설명 | 예 |
---|---|---|
hmac.policy_name.message |
정책은 Message 요소에 지정된 메시지 템플릿을 평가한 결과인 유효 메시지를 사용하여 이 변수를 설정합니다. |
hmac.HMAC-Policy.message = "Hello, World" |
hmac.policy_name.output |
Output 요소가 변수 이름을 지정하지 않으면 HMAC 계산 결과를 가져옵니다. |
hmac.HMAC-Policy.output = /yyRjydfP+fBHTwXFgc5AZhLAg2kwCri+e35girrGw4= |
hmac.policy_name.outputencoding |
출력 인코딩의 이름을 가져옵니다. | hmac.HMAC-Policy.outputencoding = base64 |
일반적인 문제
HMAC 정책은 일면 간단해 보입니다. 즉, 키와 메시지를 제공하고 응답에서 계산된 HMAC를 가져오면 됩니다. 알려진 메시지와 키 조합에 대해 예상치 못한 HMAC 값을 가져오는 경우 이 정책을 사용하면 문제가 발생할 수 있습니다. 이 섹션에서는 이러한 문제를 해결하기 위한 몇 가지 사용 참고사항을 설명합니다.
인증 과정에서 HMAC가 일치하지 않게 되는 두 가지 일반적인 문제로는 메시지의 공백 차이, 인코딩 및 디코딩의 차이가 있습니다.
후자는 SecretKey
요소와 Output
요소 모두에 적용됩니다.
공백 차이
사람에게 중요치 않은 것처럼 보이는 차이도 출력 HMAC 값에 영향을 줍니다. 예를 들어 'Secret123'으로 표현할 수 있는 보안 비밀 키가 있다고 가정해 보겠습니다. UTF-8 디코딩을 사용하면 키 바이트는 [53 65 63 72 65 74 31 32 33]
이 됩니다. 이 키를 사용하여 abc
메시지에서 HMAC-SHA256을 계산하면 a7938720fe5749d31076e6961360364c0cd271443f1b580779932c244293bc94
가 발생합니다.
메시지에 단일 공백을 추가하면 abc<SPACE>
가 되고 여기서 <SPACE>
는 ASCII 32를 나타내므로 HMAC-SHA256이 274669b2a85d2532da48e2ce3d8e52ee17346d1bcd1a606d87db1934b5ab294b
가 됩니다.
마찬가지로 메시지가 abc<NEWLINE>
이고 여기서 <NEWLINE>
이 ASCII 10을 나타내는 경우 HMAC는 0780370844ca07f896066837e8230d3b6a775f678a4ae03e6b5e864c674831f5
입니다.
메시지를 약간 변경하면 HMAC 값이 크게 달라집니다. 처음부터 그렇게 설계되어 있습니다.
이는 HMAC의 의도되고 바람직한 동작입니다.
요점은 원본 HMAC를 계산하는 데 사용되는 메시지 본문과 HMAC를 확인하는 데 사용되는 메시지 본문이 정확히 동일한지 확인하는 것이 중요하다는 것입니다. HMAC 확인자가 공백을 추가하거나 텍스트 형식을 변경하여 메시지 페이로드를 어떤 식으로든 변경하면 계산된 HMAC가 변경됩니다.
정책 구성에서 메시지 템플릿을 사용할 때는 특히 주의하세요. 예를 들어 다음 정책 구성 조각은 잠재적인 문제를 보여줍니다.
<HMAC name='HMAC-1'> ... <!-- the result of this message template will include surrounding whitespace --> <Message> {request.content} </Message> ... </HMAC>
<Message>
요소 내 메시지 템플릿 평가 결과에서는 메시지 콘텐츠 주위에 줄바꿈과 공백이 포함됩니다. 이는 의도된 결과가 아닐 수 있습니다. 더 나은 구성은 다음과 같습니다.
<HMAC name='HMAC-1'> ... <Message>{request.content}</Message> ... </HMAC>
인코딩 차이
동일한 키 자료를 다르게 디코딩하면 다른 키가 생성됩니다. 'U2VjcmV0S2V5MTIz'로 표시될 수 있는 보안 비밀 키가 있다고 가정해 보겠습니다. UTF-8 디코딩을 사용하면 base16으로 표시된 키 바이트가 [55 32 56 6a 63 6d 56 30 53 32 56 35 4d 54 49 7a]
가 됩니다.
base64 디코딩을 사용하면 키 바이트는 [53 65 63 72 65 74 4b 65 79 31 32 33]
이 됩니다.
소스 자료를 다르게 디코딩하면 키가 달라지고 결과적으로 HMAC 값이 달라집니다.
요점은 원본 HMAC를 계산하는 데 사용되는 키 자료와 HMAC를 확인하는 데 사용되는 키가 정확히 동일한지 확인하는 것이 중요하다는 것입니다. 이것은 양쪽 끝에서 동일한 키 인코딩이 사용되도록 보장한다는 것을 의미합니다. HMAC 정책에서 SecretKey
요소의 encoding
속성을 사용하여 키 인코딩을 지정할 수 있습니다.
출력에 대한 인코딩도 고려하세요. base16으로 표현된 HMAC-SHA256 또는 27f17e11c8ece93844c5eb5e55161d993368628a214f9a51c25d0185e8ea06e2
의 16진수 인코딩은 J/F+Ecjs6ThExeteVRYdmTNoYoohT5pRwl0BhejqBuI=
의 base64 인코딩 형식으로 표현된 HMAC-SHA256과 동일합니다.
두 문자열은 서로 다르게 보이지만 동일한 값을 나타냅니다. 처음에 계산된 HMAC 및 확인 HMAC를 인코딩하는 데 동일한 인코딩이 사용되어야 합니다. HMAC 정책에서 Output
요소의 encoding
속성을 사용하여 원하는 출력 인코딩을 지정하고 VerificationValue
요소의 동일한 속성을 사용하여 확인자를 디코딩하는 방법을 지정할 수 있습니다.
오류 참조
이 섹션에서는 반환되는 오류 코드 및 오류 메시지와 이 정책이 오류를 트리거할 때 Apigee에서 설정한 오류 변수를 설명합니다. 오류를 처리하기 위해 오류 규칙을 개발 중인 경우, 이 정보는 중요합니다. 자세한 내용은 정책 오류에 대해 알아야 할 사항 및 오류 처리를 참조하세요.
런타임 오류
이러한 오류는 정책이 실행될 때 발생할 수 있습니다.
오류 코드 | HTTP 상태 | 발생 상황 |
---|---|---|
steps.hmac.UnresolvedVariable |
401 | 이 오류는 HMAC 정책에 지정된 변수가 다음 중 하나인 경우에 발생합니다.
|
steps.hmac.HmacVerificationFailed |
401 | HMAC 인증에 실패했습니다. 제공된 확인 값이 계산된 값과 일치하지 않습니다. |
steps.hmac.HmacCalculationFailed |
401 | 정책에서 HMAC를 계산할 수 없습니다. |
steps.hmac.EmptySecretKey |
401 | 보안 비밀 키 변수의 값이 비어 있습니다. |
steps.hmac.EmptyVerificationValue |
401 | 확인 값을 포함하는 변수가 비어 있습니다. |
배포 오류
이 오류는 이 정책이 포함된 프록시를 배포할 때 발생할 수 있습니다.
오류 이름 | HTTP 상태 | 발생 상황 |
---|---|---|
steps.hmac.MissingConfigurationElement |
401 | 이 오류는 필수 요소 또는 속성이 누락된 경우에 발생합니다. |
steps.hmac.InvalidValueForElement |
401 | 이 오류는 알고리즘 요소에 지정된 값이 SHA-1 , SHA-224 , SHA-256 , SHA-512 , MD-5 값 중 하나가 아닌 경우 발생합니다. |
steps.hmac.InvalidSecretInConfig |
401 | 이 오류는 SecretKey 에 명시적으로 제공된 텍스트 값이 있을 때 발생합니다. |
steps.hmac.InvalidVariableName |
401 | 이 오류는 SecretKey 변수에 private 프리픽스(private. )가 포함되지 않은 경우 발생합니다. |
오류 변수
이러한 변수는 런타임 오류가 발생하면 설정됩니다. 자세한 내용은 정책 오류에 대해 알아야 할 사항을 참조하세요.
변수 | 장소 | 예 |
---|---|---|
fault.name="fault_name" |
fault_name은 위의 런타임 오류 표에 나열된 오류 이름입니다. 오류 이름은 오류 코드의 마지막 부분입니다. | fault.name Matches "UnresolvedVariable" |
hmac.policy_name.failed |
이 정책은 실패한 경우 이 변수를 설정합니다. | hmac.HMAC-Policy.failed = true |
오류 응답 예시
오류 처리에서 오류 응답의 errorcode
부분을 트래핑하는 것이 가장 좋습니다. 변경될 수 있으므로 faultstring
의 텍스트에 의존하지 마세요.
오류 규칙 예시
<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>