GH GambleHub

요청의 서명 및 검증

요청의 서명은 발신자의 진위 및 콘텐츠의 무결성을 증명합니다. TLS (채널을 보호하는) 와 달리 적용된 서명은 각 메시지를 검증 가능하고 프록시, 캐시 및 지연된 전달에 저항합니다.

목표:

1. 진실 (보낸 사람) 과 성실 (변경되지 않음).

2. 독창성 (재생에 대한 보호).

3. 전송에서 분리하기 (TP, 대기열, 웹 후크 위에서 작동).

4. 감사성 (몇 달 후 재현 가능한 점검).

1) 위협 모델 (최소)

경로를 따라 차체/헤더를 대체합니다.
재생 (합법적 인 요청 반복).
다운 그레이드/스트립 캡션.
통합 도둑질 비밀.
비 동기 시계 (시계 왜곡) 및 긴 대기열.

2) 원시의 선택

HMAC (대칭): 간단하고 빠르면 키가 양쪽에 저장됩니다. B2B 웹 후크 및 내부 API에 적합합니다.
SA/ECDSA (비대칭): 발신자의 개인 키, 수신자의 공개 키. 공개 통합 및 비밀을 공유하지 않는 것이 중요 할 때 적합합니다.
mTLS: 전송 계층 상호 인증은 종종 NMAC/본체 서명과 결합됩니다.
JWT/JWS: 소지자 토큰 및 자급 자족 스탬프에 편리합니다. 본문에 서명하려면 canonicalization + JWS Detached/SHT 메시지 서명을 사용하는 것이 좋습니다.
HTTV 메시지 서명 (요청의 선택된 부분의 서명): REST에 대한 최신 접근 방식.

추천: 웹 후크 - HMAC + 타임 스탬프 + nonce + body canonicalization; 공개 API의 경우 - STP 메시지 서명 또는 JWS; 높은 위험에서-mTLS를 추가하십시오.

3) 정식 (정확히 우리가 서명 한 것)

양 당사자가 똑같이 복구 할 수있는 결정 론적 문자열에 서명해야합니다.

참조 구성:

method \n path_with_query_normalized \n content-type \n digest: SHA-256=BASE64(SHA256(body)) \n x-ts: <unix    iso> \n x-nonce: <uuid> \n host \n x-tenant: <tenant_id> \n
총 행:

canonical = join("\n", fields)
signature = HMAC(secret, canonical)  # или ECDSA_sign(private_key, canonical)
규칙:
  • 쿼리 매개 변수의 경로와 순서를 정규화하십시오.
  • 공간/유니 코드/케이스-수정 (예: 소문자 헤더, 트림).
  • 큰 몸체-해시 (다이제스트), "그대로" 켜지 마십시오.

4) 제목 형식

HMAC의 예:

X-Signature-Alg: hmac-sha256
X-Signature: v1=hex(hmac),ts=1730379005,nonce=550e8400-e29b-41d4-a716-446655440000,kid=prov_42
Digest: SHA-256=BASE64(SHA256(body))
X-Tenant: brand_eu
비대칭 (ECDSA P-256) 의 예:

Signature: keyId="prov_42", alg="ecdsa-p256-sha256",
ts="2025-10-31T12:30:05Z", nonce="550e...", headers="(request-target) host digest x-tenant",
sig="BASE64(raw_signature)"

'kid '/' key' 를 사용하면 레지스트리에서 키를 선택할 수 있습니다 (회전 참조).

5) 수신 종료시 검증

의사 코드:
python def verify(request):
1) Basic assert abs (now () - request. ts) <= ALLOWED_SKEW  # напр., 300 с assert not replayed(request. nonce, window = TTL) # store nonce/ts in KV

2) Restore canonical canonical = build_canonical (
method=request. method,
path=normalize_path(request. path, request. query),
content_type=request. headers["content-type"],
digest=hash_body(request. body),
ts=request. ts,
nonce=request. nonce,
host=request. headers["host"],
tenant=request. headers. get("x-tenant")
)

3) Get the key key = key_registry. get(request. kid) # secret (HMAC) или public key (ECDSA)

4) Verify if request signature. alg. startswith("hmac"):
ok = hmac_compare(key. secret, canonical, request. signature)
else:
ok = asym_verify(key. public, canonical, request. signature)

5) Solution if not ok: return 401, "SIGNATURE_INVALID"
return 200, "OK"

일정한 시간 HMAC 비교, 'nonce '/' (ts, 이벤트 _ id)' 를 빠른 KV (TTL

6) 재생 방지 및 창문

타임 스탬프 + Nonce: '계정' 보다 오래된 요청을 거부합니다 (예: 5 분) 이 창에서 nonce를 다시 시도하십시오.
웹 후크의 경우: 안정적인 '이벤트 _ id' 및받은 편지함 테이블을 사용하십시오. 이것은 nonce보다 더 안정적입니다.
재 전달 (배상) 은 새 것을 생성하지 않고 동일한 ts/nonce/이벤트 _ id를 사용해야합니다.

7) 멀티 테넌트 및 지역

임차인/지역당 저장 키: 'kid = <tenit>: <region>: <key _ id>'.

별도의 비밀 수영장과 한계; 데이터 레지던트를 관찰하십시오

제목/표준화에서 'X-Tenant' 를 나타내며 해당 영역은 점검중인 컨텍스트의 일부입니다.

8) 주요 관리 및 교체

키 레지스트리 (KMS/Vault): 'kid', 유형, 알고리즘, 상태 ('액티브', '사용하지 않음', '폐기'), '유효한 _ from/유효한 _ to'.
이중 비밀: 현재 키와 다음 키를 동시에 유지하십시오 (수신기는 둘 다 허용합니다).
일정과 이벤트에 대한 회전 (타협).
키 피닝 (가능한 경우) 및 주요 재료에 대한 액세스 제한.
키와 동작에 대한 액세스 로그.

9) mTLS 및 OAuth와의 조합

mTLS는 인증서 수준에서 채널과 "당신이 누구인지" 를 확인합니다.
서명은 메시지를 보호합니다 (프록시/캐시/대기열을 통해 유용).
OAuth/JWT는 인증/인증을 보완하지만 자체적으로 신체의 무결성을 보장하지는 않습니다 (정식 화에 서명하지 않는 한).
모범 사례: mSL + 바디 시그니처 (다이제스트) + HMAC/ECDA + 짧은 'ts' 간격.

10) 오류 및 응답 코드

'401 SIGNATURE _ INVALID' 는 잘못된 서명/알고리즘입니다.
'401 KEY _ REVOKED' - 'kid' 가 유효하지 않거나 만료되었습니다.
'400 TIMESTAMP _ OUT _ OF _ RANGE' -시계/창.
'409 NONCE _ REPLAYED' -다시 감지되었습니다.
'400 ECR _ MISMATCH' -본문이 변경되었습니다.
'415 UNSUPPORTED _ ALGORITHM' 은 해결되지 않은 'alg' 입니다.
'429 TOO _ MANY _ ATTEMPTS' -키/테넌트 스로틀.

기계에서 읽을 수있는 '오류 _ 코드' 의 정확한 원인을 걷어차 십시오. "그대로" 비밀/표준화를 반환하지 마십시오.

11) 관찰 및 감사

메트릭:
  • '확인 _ p95 _ ms', '확인 _ orr _ rate', 'digest _ mission _ rate', 'replay _ blacked _ rate', 'alg _ usage {hmac, ecdsa}', 'clock _ skew _ ms'.
  • 통나무 (구조): 'kid', 'alg', 'tentin', 'region', 'ts', 'nonce', 'digest _ hash', 'decision', 'reason'.
  • 추적: 속성의 서명. 어린이 ',' 서명. alg ',' 서명. ts _ skew '.
  • 감사: 불변의 회전 로그, 주요 사용 및 공차 플래그.

12) 성능

스트리밍하여 몸을 해시하십시오 (메모리에 보관하지 마십시오).
짧은 TTL과 이벤트 별 장애가있는 'kid' 로 공개 키를 캐시하십시오.
모서리/게이트웨이에서 예비 점검 (ts/nonce/form) 을 수행하십시오.
ECDSA보다 빠른 HMAC; ECDSA는 외부 통합 및 "비 공유" 키에 더 편리합니다.

13) 테스트

일정 세트: 동일한 요청 → 동일한 정식/서명; 더러운 공간/쿼리 순서/→ 헤더는 안정적입니다.
부정적: 유효하지 않은 'kid/alg', 수정 된 본체/호스트, nonce repess, 쓸모없는, 시계 왜곡.
속성 기반: 동등한 쿼리는 단일 표준 문자열을 생성합니다.
Interop: 언어 간 검사 (Go/Java/Node/Pine).
혼돈: 지연, 퇴각, 즉석 키 변경.

14) 플레이 북 (런북)

1. 'SIGNATURE _ INVALID' 스파이크

발신자의 키 회전, 클럭 정렬 오류, 정식 변경 사항을 확인하십시오.

오래된 '어린이' 에 대해 일시적으로 '이중 수락' 을 가능하게합니다. 파트너에게

2. 'REPLAYED' 성장

nonce 스토리지의 TTL을 높이고 발신자의 리트레이너를 확인하고 시계 왜곡을 확인하십시오.
가장자리에서 모욕적 인 IP/ASN을 무시하십시오.

3. '에스컬레이션 _ MISMATCH' 대규모

프록시/압축/재 작성 헤더를 확인하십시오. canonicalization 버전을 수정합니다.
차체/헤더 침입자를 사용하지 않습니다.

4. 주요 타협

즉시 'kid' 를 취소하고 'nethern _ kid' 로 번역하고 모든 비밀/토큰을 재생성하고 액세스를 감사합니다.

15) 전형적인 오류

필드 순열에 대한 주문 → 취약성을 수정하지 않고 "신체 부위" 또는 JSON에 서명합니다.
'다이제스트' → 프록시가 없으면 신체가 눈에 띄지 않게 변할 수 있습니다.
nonce가없는 긴 'ts' 창은 → 재생을 위해 열려 있습니다.
KMS/Vault없이 환경 변수에 비밀을 유지하십시오.
일정한 시간이 아닌 서명을 비교하십시오.
표준화 → 전방 공격에서 '호스트 '/' 경로' 를 무시하십시오.
'어린이' 다른 세입자와 지역을 혼합하십시오.

16) 사전 판매 점검표

  • 정의 된 정식 형식 (메소드, 경로 + 쿼리, 컨텐츠 유형, 다이제스트, ts, nonce, 호스트, 테넌트).
  • 'kid', 키 레지스트리 및 이중 비밀로 HMAC/ECDSA를 구현했습니다.
  • 웹 후크 용 재생 방지 (nonce + ts) 및받은 편지함/이벤트 _ id 스토리지가 포함되어 있습니다.
  • 임차인/키당 오류 코드/재 트레이 정책 및 스로틀 링.
  • 관찰 가능성: 메트릭, 로그, 추적, 버스트 경고 확인.
  • 키 회전이 자동화됩니다. 감사 및 액세스 권한은 제한되어 있습니다.
  • 정식 및 언어 간 호환성 테스트 키트.
  • 3-4 개 언어 및 수정 사항이 포함 된 통합 자에 대한 문서.

민감한 통합을 위해 [] mTLS를 사용할 수 있습니다. JWT는 신체 서명을 대체하는 것이 아니라 추가로만 사용됩니다.

결론

요청에 서명하고 확인하는 것은 "하나의 헤더" 가 아니라 명확한 정식 화, 짧은 시간 창, 재생 방지, 키 회전 및 관찰 가능성입니다. 모든 통합 (API 및 웹 후크) 에 대한 단일 표준을 작성하고 'kid '/KMS를 사용하고 회전 중에 두 개의 키를 수락하면 윤곽이 스푸핑에 강하고 예측 가능하며 감사하기 쉽습니다.

Contact

문의하기

질문이나 지원이 필요하시면 언제든지 연락하십시오.우리는 항상 도울 준비가 되어 있습니다!

Telegram
@Gamble_GC
통합 시작

Email — 필수. Telegram 또는 WhatsApp — 선택 사항.

이름 선택 사항
Email 선택 사항
제목 선택 사항
메시지 선택 사항
Telegram 선택 사항
@
Telegram을 입력하시면 Email과 함께 Telegram에서도 답변드립니다.
WhatsApp 선택 사항
형식: +국가 코드 + 번호 (예: +82XXXXXXXXX).

버튼을 클릭하면 데이터 처리에 동의하는 것으로 간주됩니다.