개요
Planet Security REST API를 사용하면 외부 웹사이트에서 Planet 로그인을 연동할 수 있습니다. 비밀번호 없이, 행성의 실시간 회전 상태 기반 상호 인증으로 로그인합니다.
Planet Security는 암호화가 아닌 일방향 상태 바인딩입니다. 비밀 자체를 생성하지 않으므로 탈취될 수 없습니다. 공격의 유일한 결과는 세션 실패입니다.
빠른 시작 (3단계)
1단계: 앱 등록
아래 양식으로 앱을 등록하면 API Key가 발급됩니다.
2단계: SDK 삽입 (가장 간단한 방법)
HTML에 스크립트 한 줄과 로그인 버튼을 추가하세요.
<!-- Planet Security SDK -->
<script src="https://planet.winnerbrothers.org/api/v1/sdk"></script>
<!-- 로그인 버튼 (자동 렌더링) -->
<div
data-planet-login
data-planet-key="YOUR_API_KEY"
data-planet-theme="dark"
data-planet-size="medium"
></div>
<!-- 또는 JavaScript로 직접 제어 -->
<script>
PlanetSecurity.init({
apiKey: 'YOUR_API_KEY',
onAuth: function(result) {
if (result.success) {
console.log('인증 성공:', result.username);
console.log('행성 검증 정보:', result.planetVerification);
// 서버에 result.requestId를 보내서 검증
}
}
});
// 버튼 렌더링
PlanetSecurity.renderButton('#login-container', {
theme: 'dark',
size: 'medium'
});
</script>3단계: 서버에서 검증
콜백으로 받은 planet_token을 서버에서 검증합니다.
// 콜백 URL로 리다이렉트됨:
// https://myblog.com/auth/callback?planet_token=req_xxx&username=user1
// 서버에서 상태 확인
const response = await fetch(
'https://planet.winnerbrothers.org/api/v1/auth/status?request_id=' + planet_token,
{
headers: {
'Authorization': 'Bearer YOUR_API_KEY'
}
}
);
const data = await response.json();
// {
// requestId: "req_xxx",
// status: "authenticated",
// username: "user1",
// planetVerification: {
// serverPlanetId: "...",
// rotationAxis: { x, y, z },
// angularSpeed: 42.5
// }
// }API 레퍼런스
인증 (Authentication)
/api/v1/apps/register외부 앱 등록 (API Key 발급)
{ "name": "My App", "domain": "example.com", "callbackUrl": "https://..." }{ "appId": "app_xxx", "apiKey": "pk_xxx" }/api/v1/auth/init인증 요청 생성 → loginUrl 반환
Authorization: Bearer API_KEY{ "redirectUrl": "https://..." }{ "requestId": "req_xxx", "loginUrl": "...", "expiresAt": ... }/api/v1/auth/status?request_id=req_xxx인증 상태 확인
Authorization: Bearer API_KEY{ "status": "authenticated", "username": "user1", "planetVerification": {...} }보안 토큰 (OTP 대체)
/api/v1/tokens/issue일회용 보안 토큰 발행 (행성 상태 바인딩)
Authorization: Bearer API_KEY{ "planetId": "xxx", "purpose": "login-2fa", "ttlSeconds": 300 }{ "tokenId": "tok_xxx", "planetStateHash": "...", "expiresAt": ... }/api/v1/tokens/verify토큰 검증 및 소비 (1회 사용)
Authorization: Bearer API_KEY{ "tokenId": "tok_xxx" }{ "valid": true, "purpose": "login-2fa", "consumedAt": ... }/api/v1/tokens/status?token_id=tok_xxx토큰 상태 조회 (소비하지 않음)
Authorization: Bearer API_KEY{ "status": "active", "purpose": "login-2fa", "expiresAt": ... }상태 서명 (전자서명 대체)
/api/v1/state/capture행성의 현재 상태 캡처 (쿼터니언 + 좌표)
Authorization: Bearer API_KEY{ "planetId": "xxx" }{ "stateHash": "...", "quaternion": {w,x,y,z}, "coordinates": {...} }/api/v1/state/sign데이터에 행성 상태 서명 (문서 인증)
Authorization: Bearer API_KEY{ "planetId": "xxx", "data": "계약서 내용..." }{ "signatureId": "sig_xxx", "stateHash": "...", "quaternion": {...} }/api/v1/state/verify상태 서명 검증
Authorization: Bearer API_KEY{ "signatureId": "sig_xxx", "data": "계약서 내용..." }{ "valid": true, "dataHashMatch": true, "signedAt": ... }데이터 바인딩 (무결성 보장)
/api/v1/data/bind데이터를 행성 상태에 바인딩
Authorization: Bearer API_KEY{ "planetId": "xxx", "data": "중요 데이터", "ttlSeconds": 3600 }{ "bindingId": "bind_xxx", "stateHash": "...", "expiresAt": ... }/api/v1/data/verify바인딩된 데이터 무결성 검증
Authorization: Bearer API_KEY{ "bindingId": "bind_xxx", "data": "중요 데이터" }{ "valid": true, "dataIntegrity": "intact" }보안 메시징
/api/v1/messaging/send상태 바인딩 메시지 전송
Authorization: Bearer API_KEY{ "senderPlanetId": "xxx", "receiverPlanetId": "yyy", "content": "..." }{ "messageId": "msg_xxx", "stateHash": "..." }/api/v1/messaging/verify수신 메시지 검증
Authorization: Bearer API_KEY{ "messageId": "msg_xxx", "receiverPlanetId": "yyy" }{ "valid": true, "content": "...", "verifiedAt": ... }/api/v1/messaging/history?planet_id=xxx메시지 이력 조회
Authorization: Bearer API_KEY{ "count": 10, "messages": [...] }Planet Coin (디지털 화폐)
/api/v1/coin/wallet코인 지갑 생성 (행성에 연결)
Authorization: Bearer API_KEY{ "planetId": "xxx", "owner": "민수" }{ "walletId": "wal_xxx", "balance": 0 }/api/v1/coin/wallet?wallet_id=xxx지갑 조회 (잔액, 행성 정보)
Authorization: Bearer API_KEY{ "walletId": "...", "balance": 50000, "balancePCN": 5.0, "planetVolume": ... }/api/v1/coin/wallet?list=true앱의 전체 지갑 목록
Authorization: Bearer API_KEY{ "count": 5, "wallets": [...] }/api/v1/coin/mint코인 발행 (행성 상태 기반)
Authorization: Bearer API_KEY{ "walletId": "wal_xxx", "amount": 100.0, "description": "초기 발행" }{ "txId": "tx_xxx", "txHash": "...", "newBalancePCN": 100.0 }/api/v1/coin/transfer코인 전송 (상호 행성 상태 검증)
Authorization: Bearer API_KEY{ "fromWalletId": "wal_a", "toWalletId": "wal_b", "amount": 5.0, "type": "purchase" }{ "txId": "tx_xxx", "txHash": "...", "senderStateHash": "...", "receiverStateHash": "..." }/api/v1/coin/ledger?wallet_id=xxx거래 상태 원장 조회
Authorization: Bearer API_KEY{ "total": 20, "summary": { "totalMintedPCN": 100, ... }, "entries": [...] }/api/v1/coin/verify거래 검증
Authorization: Bearer API_KEY{ "txId": "tx_xxx" }{ "valid": true, "txHash": "...", "verification": "..." }Post-Quantum (양자 내성)
/api/v1/pq/keygenML-KEM-768 + ML-DSA-65 키쌍 생성
Authorization: Bearer SECRET_KEY{ "kem": { "algorithm": "ML-KEM-768", "publicKey": "...", "secretKey": "..." }, "dsa": { "algorithm": "ML-DSA-65", ... } }/api/v1/pq/encapsulateML-KEM 키 캡슐화 (공유 비밀 생성)
Authorization: Bearer SECRET_KEY{ "recipientPublicKey": "base64..." }{ "cipherText": "...", "sharedSecret": "256-bit base64" }/api/v1/pq/decapsulateML-KEM 키 역캡슐화 (공유 비밀 복원)
Authorization: Bearer SECRET_KEY{ "cipherText": "base64...", "secretKey": "base64..." }{ "sharedSecret": "256-bit base64" }/api/v1/pq/signML-DSA-65 양자 내성 전자서명
Authorization: Bearer SECRET_KEY{ "data": "서명할 데이터", "secretKey": "base64..." }{ "signature": "base64...", "algorithm": "ML-DSA-65" }/api/v1/pq/verifyML-DSA-65 서명 검증
Authorization: Bearer SECRET_KEY{ "data": "...", "signature": "base64...", "publicKey": "base64..." }{ "valid": true, "algorithm": "ML-DSA-65" }HSM (Hardware Security Module)
/api/v1/hsm/statusHSM 상태 조회 (provider, mode, FIPS 준수)
Authorization: Bearer SECRET_KEY{ "provider": "Planet SoftHSM v1.0", "mode": "software", "fipsCompliant": true, "usedSlots": 5 }/api/v1/hsm/storeHSM에 키 저장 (행성 파라미터/서명키)
Authorization: Bearer SECRET_KEY{ "label": "Planet-A", "keyType": "planet-params", "owner": "user1", "keyData": "..." }{ "slotId": "hsm_xxx", "fingerprint": "abc123...", "status": "active" }/api/v1/hsm/list?owner=user1HSM 키 슬롯 목록 조회
Authorization: Bearer SECRET_KEY{ "count": 3, "slots": [{ "slotId": "...", "label": "...", "accessCount": 42 }] }Galaxy Protocol (분산 행성 네트워크)
/api/v1/galaxy/nodesGalaxy 노드 등록
Authorization: Bearer SECRET_KEY{ "name": "Seoul-1", "endpoint": "https://seoul.planet.io", "region": "ap-northeast-2" }{ "nodeId": "node_xxx", "status": "active" }/api/v1/galaxy/nodesGalaxy 노드 목록
Authorization: Bearer SECRET_KEY{ "count": 3, "nodes": [{ "nodeId": "...", "name": "Seoul-1", "status": "active" }] }/api/v1/galaxy/sync행성 상태 노드 간 동기화
Authorization: Bearer SECRET_KEY{ "fromNodeId": "node_a", "toNodeId": "node_b", "planetId": "xxx" }{ "syncId": "sync_xxx", "stateHash": "...", "verified": true }/api/v1/galaxy/healthGalaxy 네트워크 헬스체크
Authorization: Bearer SECRET_KEY{ "totalNodes": 3, "activeNodes": 3, "networkStatus": "healthy" }작동 원리
방산 / 무기체계 / 위성 통신용 API
무기 시스템·UAV·UGV·위성·전술 통신망에 즉시 통합 가능한 OSF 기반 인증 API입니다. 명령 탈취·재전송·MITM·Hijack·시각 위조 공격을 단일 primitive로 차단합니다 (Theorems 1·2·6).
모든 엔드포인트는 secret key (sk_) 필수. 시연용 API key는 상단 1단계에서 즉시 발급. 1조+ PoC 계약은 official@winnerbrothers.org로 문의.
환경별 시각 윈도우 Δ (Theorem 6)
운영 환경에 맞는 environment 필드를 선택하면 서버가 자동으로 적정 Δ를 적용합니다. Δ 초과 시 명령은 자동 거부 (clock_skew_exceeds_delta).
| environment | Δ | 활용 환경 | 시각 동기 인프라 |
|---|---|---|---|
| gps_disciplined | 100μs | PTP 정밀 동기 (위성 페이로드, GNSS 수신기) | PTP·GPS-disciplined OCXO |
| datacenter | 1ms | 단일 랙·MEC·GCS 데이터센터 | 고정밀 NTP, 1588 PTP |
| lan | 10ms | 군 내부망·KJCCS·전술 LAN | NTP |
| field | 50ms | 전술 야전·드론 GCS·전자전 환경 | NTP fallback, GPS |
| satellite | 100ms | LEO/MEO/GEO 위성-지상국 | 위성 GPS·온보드 클럭 |
| space | 500ms | 심우주·GPS-denied (전자전 강한 재밍) | 관성 항법 + 자체 클럭 |
대표 활용 시나리오
field Δ=50ms.satellite. Forward Secrecy로 K 노출 시에도 과거 세션 보호.field Δ=50ms. CSPRNG K 격리 (HSM).datacenter(고정밀) ~ field.빠른 시작 — curl 5분 통합
전체 8개 엔드포인트를 5분 안에 walk-through. 서버에 jq, openssl 필요.
# 1) 1·2단계 키 발급 — GCS와 무인체계 등록
GCS=$(curl -s -X POST $BASE/api/v1/defense/keygen \
-H "Authorization: Bearer $SK" -H "Content-Type: application/json" \
-d '{"callsign":"GCS-01","classification":"gcs","environment":"field"}')
UAV=$(curl -s -X POST $BASE/api/v1/defense/keygen \
-H "Authorization: Bearer $SK" -H "Content-Type: application/json" \
-d '{"callsign":"EAGLE-01","classification":"uav","environment":"field"}')
GCS_ID=$(echo "$GCS" | jq -r .device.deviceId)
UAV_ID=$(echo "$UAV" | jq -r .device.deviceId)
# 2) 3-Round 상호 인증 (Theorem 2 + 4)
INIT_PUB=$(openssl ecparam -name prime256v1 -genkey -noout | \
openssl ec -pubout -outform DER 2>/dev/null | tail -c 65 | xxd -p | tr -d '\n')
INIT_HASH=$(echo -n "$INIT_PUB" | openssl dgst -sha256 | awk '{print $2}')
RESP_PUB=$(openssl ecparam -name prime256v1 -genkey -noout | \
openssl ec -pubout -outform DER 2>/dev/null | tail -c 65 | xxd -p | tr -d '\n')
R1=$(curl -s -X POST $BASE/api/v1/defense/handshake/init \
-H "Authorization: Bearer $SK" -H "Content-Type: application/json" \
-d "{\"initiatorDeviceId\":\"$GCS_ID\",\"responderDeviceId\":\"$UAV_ID\",\"initEphemeralPubHash\":\"$INIT_HASH\"}")
HS_ID=$(echo "$R1" | jq -r .handshakeId)
curl -s -X POST $BASE/api/v1/defense/handshake/respond \
-H "Authorization: Bearer $SK" -H "Content-Type: application/json" \
-d "{\"handshakeId\":\"$HS_ID\",\"respondEphemeralPub\":\"$RESP_PUB\"}"
curl -s -X POST $BASE/api/v1/defense/handshake/finalize \
-H "Authorization: Bearer $SK" -H "Content-Type: application/json" \
-d "{\"handshakeId\":\"$HS_ID\",\"initEphemeralPub\":\"$INIT_PUB\"}"
# 3) 명령 서명 → 전송 → 검증 (Theorem 1, 6)
SIGN=$(curl -s -X POST $BASE/api/v1/defense/command/sign \
-H "Authorization: Bearer $SK" -H "Content-Type: application/json" \
-d "{\"handshakeId\":\"$HS_ID\",\"senderDeviceId\":\"$GCS_ID\",\"command\":\"TAKEOFF altitude=50m\"}")
BUNDLE=$(echo "$SIGN" | jq -c .signedCommand)
# 수신자(드론)가 검증 — 위조 advantage <= q_H * 2^-159
curl -s -X POST $BASE/api/v1/defense/command/verify \
-H "Authorization: Bearer $SK" -H "Content-Type: application/json" \
-d "$BUNDLE"
# {"valid":true,"advBound":"Adv ≤ q_H · 2⁻¹⁵⁹","skewMs":3,"deltaMs":50,...}
# 같은 번들 재전송 → Replay 거부
curl -s -X POST $BASE/api/v1/defense/command/verify -d "$BUNDLE" $H
# {"valid":false,"reason":"replay_detected"}전체 스크립트: /samples/curl/quickstart.sh · 8개 시나리오 통합 테스트: scripts/defense-integration-test.mjs
SDK / 코드 샘플
planet_defense_sdk.py · GCS·드론·위성 GroundOps 즉시 사용. cryptography + 표준 라이브러리만 필요.planet_mavlink_wrapper.py · PX4·ArduPilot 위 즉시 layered. COMMAND_LONG/INT 자동 OSF 래핑.planet_defense_embedded.c · mbedTLS 의존 ~3.2KB .text · <5ms 인증 · ring buffer replay 64. Pixhawk·PIC32·STM32.quickstart.sh · 8개 엔드포인트 5분 walk-through + Replay 차단 시연. CI/CD에 그대로 삽입 가능.Defense API 엔드포인트 (8개)
/api/v1/defense/statuscapability matrix·환경별 Δ 테이블·정리(Theorem) 목록·플릿 통계 (Public Key OK)
Authorization: Bearer pk_...{
"serverTime": 1714888888888,
"capability": { "classicalSecurityBits": 159, "pqSecurityBits": 79, ... },
"environments": [
{ "environment": "lan", "deltaMs": 10, ... },
{ "environment": "satellite", "deltaMs": 100, ... }
],
"theorems": [
{ "id": 1, "name": "Authentication Unforgeability", "model": "ROM", "bound": "Adv ≤ q_H · 2⁻¹⁵⁹" },
{ "id": 5, "name": "Post-Quantum (QROM)", "model": "QROM", "bound": "79-bit PQ" },
...
],
"fleet": { "totalDevices": 12, "activeDevices": 11, ... }
}/api/v1/defense/keygenK=(â, ω, p₀) 트리플 생성 · CSPRNG (FIPS 140-3) · HSM 격리 가정
Authorization: Bearer sk_...{
"callsign": "EAGLE-01",
"classification": "uav", // gcs | uav | ugv | usv | satellite | weapon | sensor | soldier | vehicle
"environment": "field", // gps_disciplined | datacenter | lan | field | satellite | space
"ownerOrg": "LIG D&A",
"hsmAttested": false // production: true (HSM 증명 첨부)
}{
"success": true,
"device": { "deviceId": "dev_xxx", "deltaMs": 50, ... },
"capability": { "classicalSecurityBits": 159, "pqSecurityBits": 79, ... },
"K": { "planetId": "...", "coordinates": {...}, "rotationAxis": {...}, ... }
}/api/v1/defense/handshake/initRound 1 — Initiator 시작 + ECDH ephem pub 해시 commit
Authorization: Bearer sk_...{
"initiatorDeviceId": "dev_xxx",
"responderDeviceId": "dev_yyy",
"initEphemeralPubHash": "sha256(ECDH P-256 pub key hex)"
}{
"success": true,
"handshakeId": "hs_xxx",
"handshake": { "initNonce": "...", "initStateHash": "...", "initTimestamp": 1714..., "deltaMs": 50, ... }
}/api/v1/defense/handshake/respondRound 2 — Responder가 Initiator 상태해시 검증 후 자기 상태해시 + ECDH ephem pub 응답
Authorization: Bearer sk_...{
"handshakeId": "hs_xxx",
"respondEphemeralPub": "ECDH P-256 pub key hex"
}{
"success": true,
"handshake": { "respondNonce": "...", "respondStateHash": "...", "respondTimestamp": ..., "status": "responded" }
}/api/v1/defense/handshake/finalizeRound 3 — Initiator ECDH ephem pub 공개 (Round 1 commit 검증) → sessionKey 도출
Authorization: Bearer sk_...{
"handshakeId": "hs_xxx",
"initEphemeralPub": "ECDH P-256 pub key hex"
}{
"success": true,
"sessionKey": "sha256 of full transcript",
"deltaMs": 50,
"forwardSecrecy": "ECDH P-256 ephemeral keys ensure past sessions remain confidential ..."
}/api/v1/defense/command/signSender(GCS) 가 명령 페이로드를 sessionKey HMAC-SHA-256 으로 서명
Authorization: Bearer sk_...{
"handshakeId": "hs_xxx",
"senderDeviceId": "dev_gcs",
"command": "TAKEOFF altitude=50m"
}{
"success": true,
"signedCommand": {
"commandId": "cmd_xxx",
"command": "TAKEOFF altitude=50m",
"senderStateHash": "...",
"nonce": "...",
"timestamp": 1714...,
"signature": "HMAC-SHA-256(sessionKey, command|stateHash|nonce|ts|cmdId)"
}
}/api/v1/defense/command/verifyReceiver(드론·위성) 가 수신 번들 검증 — 4단계 (replay·시간·상태해시·HMAC)
Authorization: Bearer sk_...{ ...full signedCommand bundle from /sign... }{
"valid": true, // 또는 false + reason
"advBound": "Adv ≤ q_H · 2⁻¹⁵⁹ (Theorem 1, ROM, 159-bit classical / 79-bit PQ)",
"deltaMs": 50, "skewMs": 3,
"theorems": ["T1: Auth Unforgeability", "T2: Transcript Indistinguishability", "T6: Clock-Skew Robustness"]
}/api/v1/defense/heartbeat디바이스 liveness · 시각 동기 검증 · clock drift 사전 감지
Authorization: Bearer sk_...{
"deviceId": "dev_xxx",
"stateHash": "...", "nonce": "...", "timestamp": 1714...
}{
"healthy": true, "mode": "verified",
"deltaMs": 50, "skewMs": 2,
"serverTime": 1714...
}8개 정식 정리 매핑 (ROM/QROM 게임-홉 증명)
| Theorem | 의미 | Defense API에서 보장 |
|---|---|---|
| 1 | Authentication Unforgeability (ROM) | 위조 advantage ≤ q_H · 2⁻¹⁵⁹ |
| 2 | Transcript Indistinguishability | 네트워크 관측에서 K 추론 불가 |
| 3 | Mutual Auth Soundness | 한쪽 침해 시 반대쪽 격리 (Reveal 모델) |
| 4 | Forward Secrecy (DDH) | ECDH P-256 ephemeral · K 노출 시 과거 세션 보호 |
| 5 | Post-Quantum (QROM) | Shor 무관 · 79-bit PQ · HNDL 양자 공격 차단 |
| 6 | Clock-Skew Robustness | Δ 윈도우 내 시각 동기 견고 · GPS 재밍 환경 fallback |
| 7 | Partial State Leakage Resilience | 부분 노출 시에도 K 전체 미복구 |
| 8 | Multi-OSF Security | m=2 시 318-bit / 158-bit PQ (AES-256 초과) |
방산 표준 적합성
방산 PoC / 라이선스 문의
보안 참고
- Planet API는 Orbital State Function (OSF) 기반 시간-동기식 상호 인증을 제공합니다 (특허 PCT WO 2025/127469).
- 보안 수준: 159-bit 고전 / 79-bit 양자 — 위조 확률 상한 Adv ≤ qH · 2⁻¹⁵⁹ (수반 논문 Thm 1, ROM).
- OSF primitive는 정수분해/이산로그 미사용 — Shor 알고리즘 무관 (Thm 5).
- Transcript(해시 커밋)는 ROM 하 uniform 랜덤과 구별 불가능 (Thm 2) — 네트워크 관측으로 키 정보 누출 0.
- Secret Key(sk_)는 반드시 서버 측에서만 사용하세요. 클라이언트 코드에 절대 노출 금지.