Skip to main content

์ธ์ฆ ๋ฐฉ์‹ ์•ˆ๋‚ด

ํ”Œ๋Ÿฌ๊ทธ ์˜คํ”ˆ API๋Š” API Key + Signature ๊ธฐ๋ฐ˜์˜ ์ธ์ฆ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  API ์š”์ฒญ ์‹œ ๋‘ ๊ฐ€์ง€ ์ธ์ฆ ์ •๋ณด๋ฅผ ๋ฐ˜๋“œ์‹œ ํ—ค๋”์— ํฌํ•จํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
๋ชจ๋“  API ์š”์ฒญ ์‹œ ์•„๋ž˜ ํ—ค๋”๋ฅผ ํฌํ•จํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • X-API-KEY: ๋ฐœ๊ธ‰๋ฐ›์€ API Key
  • X-Signature: ์š”์ฒญ ๋ณธ๋ฌธ์— ๋Œ€ํ•œ HMAC ์„œ๋ช…๊ฐ’
X-Signature๊ฐ€ ์—†๋Š” ์š”์ฒญ์€ ์ธ์ฆ๋˜์ง€ ์•Š์œผ๋ฉฐ, ์„œ๋ฒ„์—์„œ ๊ฑฐ๋ถ€๋ฉ๋‹ˆ๋‹ค.
Signature๋Š” API Key ๋ฐœ๊ธ‰ ์‹œ ํ•จ๊ป˜ ์ œ๊ณต๋œ Secret Key๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  • ์•Œ๊ณ ๋ฆฌ์ฆ˜: HMAC-SHA256
  • ์„œ๋ช… ๋Œ€์ƒ: ์š”์ฒญ ๋ณธ๋ฌธ (request.body)
  • ์„œ๋ฒ„๋Š” ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋ณด๋‚ธ Signature๊ฐ€ ์œ ํšจํ•œ์ง€ ๊ฒ€์ฆํ•ฉ๋‹ˆ๋‹ค.
Signature๋Š” ์š”์ฒญ์˜ ๋ฌด๊ฒฐ์„ฑ์„ ๋ณด์žฅํ•˜๋ฉฐ, ์œ„๋ณ€์กฐ ๋ฐฉ์ง€ ๋ชฉ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ’ก ์–ธ์–ด๋ณ„ ์„œ๋ช… ์˜ˆ์‹œ

API ์š”์ฒญ ์‹œ request.body๋ฅผ ๊ธฐ์ค€์œผ๋กœ HMAC-SHA256 ์„œ๋ช…์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์š”์ฒญ ๋ณธ๋ฌธ์ด ์—†์„ ๊ฒฝ์šฐ, ์ž๋™์œผ๋กœ ๋นˆ ๋ฌธ์ž์—ด("")์„ ์„œ๋ช… ๋Œ€์ƒ์œผ๋กœ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;

public class HmacSignature {
    public static void main(String[] args) throws Exception {
        String secretKey = "your-secret-key";

        String body = getBody(); // ์š”์ฒญ ๋ณธ๋ฌธ์ด ์žˆ์œผ๋ฉด JSON ๋ฌธ์ž์—ด, ์—†์œผ๋ฉด ""

        Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
        SecretKeySpec secret_key = new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
        sha256_HMAC.init(secret_key);

        byte[] hash = sha256_HMAC.doFinal(body.getBytes(StandardCharsets.UTF_8));
        String signature = bytesToHex(hash);

        System.out.println(signature);
    }

    private static String getBody() {
        // ๋ณธ๋ฌธ์ด ์žˆ์„ ๊ฒฝ์šฐ ์ง๋ ฌํ™”๋œ ๋ฌธ์ž์—ด ๋ฐ˜ํ™˜
        // ์—†์œผ๋ฉด return "";
        return "{\"name\":\"pluuug\",\"type\":\"openapi\"}";
    }

    private static String bytesToHex(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            sb.append(String.format("%02x", b));
        }
        return sb.toString();
    }
}
import json, hmac, hashlib

payload = {"name": "pluuug", "type": "openapi"}  # ๋ณธ๋ฌธ์ด ์—†์œผ๋ฉด None
body = json.dumps(payload, separators=(",", ":")) if payload else ""

secret_key = "your-secret-key"
signature = hmac.new(secret_key.encode(), body.encode(), hashlib.sha256).hexdigest()
print(signature)
const payload = { name: "pluuug", type: "openapi" }; // ์—†์œผ๋ฉด null
const body = payload ? JSON.stringify(payload) : "";

async function generateSignature(secretKey, body) {
  const encoder = new TextEncoder();
  const key = await crypto.subtle.importKey(
    "raw",
    encoder.encode(secretKey),
    { name: "HMAC", hash: "SHA-256" },
    false,
    ["sign"]
  );
  const signature = await crypto.subtle.sign("HMAC", key, encoder.encode(body));
  return [...new Uint8Array(signature)]
    .map(b => b.toString(16).padStart(2, "0"))
    .join("");
}

generateSignature("your-secret-key", body).then(console.log);
const crypto = require("crypto");

const payload = { name: "pluuug", type: "openapi" }; // ์—†์œผ๋ฉด null
const body = payload ? JSON.stringify(payload) : "";

const secretKey = "your-secret-key";
const signature = crypto
  .createHmac("sha256", secretKey)
  .update(body)
  .digest("hex");

console.log(signature);
$payload = ['name' => 'pluuug', 'type' => 'openapi']; // ์—†์œผ๋ฉด null
$body = $payload
  ? json_encode($payload, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)
  : "";

$secretKey = 'your-secret-key';
$signature = hash_hmac('sha256', $body, $secretKey);
echo $signature;
package main

import (
    "crypto/hmac"
    "crypto/sha256"
    "encoding/hex"
    "encoding/json"
    "fmt"
)

func main() {
    payload := map[string]string{
        "name": "pluuug",
        "type": "openapi",
    }

    var bodyBytes []byte
    if payload != nil {
        bodyBytes, _ = json.Marshal(payload)
    } else {
        bodyBytes = []byte("")
    }

    secretKey := []byte("your-secret-key")
    h := hmac.New(sha256.New, secretKey)
    h.Write(bodyBytes)
    signature := hex.EncodeToString(h.Sum(nil))

    fmt.Println(signature)
}
โŒ˜I