제4장

API 구현 가이드

SDK(Software Development Kit)는 API에 대한 개발자 친화적인 인터페이스를 제공하며, HTTP 세부 사항을 추상화하고 언어별 관용구를 제공합니다. WIA-SOCIAL 표준은 TypeScript, Python, Java로 작성된 참조 SDK를 제공합니다.

SDK 모듈 주요 기능 핵심 메서드 반환 타입
Documents CRUD 작업 create(), get(), update(), delete(), list() Document, DocumentList
Verification 진위 확인 verify(), checkSignature(), getStatus() VerificationResult
Search 쿼리 및 필터링 search(), filter(), facet() SearchResults
Signatures 암호화 작업 sign(), validateSignature(), getCertificate() Signature, Certificate
Templates 문서 생성 getTemplate(), renderDocument() Template, RenderedDocument

4.1 TypeScript SDK 구현

TypeScript는 타입 안전성과 최신 JavaScript 기능을 제공하여 공공문서 API 클라이언트를 구현하기에 이상적인 언어입니다. 다음은 완전한 기능을 갖춘 WIA-SOCIAL TypeScript SDK 구현입니다.

클라이언트 초기화 및 인증

// src/client.ts
import axios, { AxiosInstance, AxiosRequestConfig } from 'axios';
import jwt_decode from 'jwt-decode';

export interface WIAConfig {
  baseURL: string;
  apiKey?: string;
  timeout?: number;
}

export interface JWTPayload {
  sub: string;
  name: string;
  role: string;
  permissions: string[];
  exp: number;
}

export class WIAPublicDocumentClient {
  private client: AxiosInstance;
  private accessToken?: string;
  private refreshToken?: string;

  constructor(config: WIAConfig) {
    this.client = axios.create({
      baseURL: config.baseURL || 'https://api.wia-social.org/v1',
      timeout: config.timeout || 30000,
      headers: {
        'Content-Type': 'application/json',
        'User-Agent': 'WIA-SDK-TypeScript/1.0.0'
      }
    });

    // Request interceptor: 토큰 자동 추가
    this.client.interceptors.request.use((config) => {
      if (this.accessToken) {
        config.headers.Authorization = `Bearer ${this.accessToken}`;
      }
      return config;
    });

    // Response interceptor: 토큰 자동 갱신
    this.client.interceptors.response.use(
      (response) => response,
      async (error) => {
        const originalRequest = error.config;

        if (error.response?.status === 401 && !originalRequest._retry) {
          originalRequest._retry = true;

          try {
            await this.refreshAccessToken();
            return this.client(originalRequest);
          } catch (refreshError) {
            return Promise.reject(refreshError);
          }
        }

        return Promise.reject(error);
      }
    );
  }

  async login(email: string, password: string): Promise {
    const response = await this.client.post('/auth/login', {
      email,
      password
    });

    this.accessToken = response.data.accessToken;
    this.refreshToken = response.data.refreshToken;
  }

  async refreshAccessToken(): Promise {
    if (!this.refreshToken) {
      throw new Error('No refresh token available');
    }

    const response = await this.client.post('/auth/refresh', {
      refreshToken: this.refreshToken
    });

    this.accessToken = response.data.accessToken;
  }

  isTokenExpired(): boolean {
    if (!this.accessToken) return true;

    try {
      const decoded = jwt_decode(this.accessToken);
      return Date.now() >= decoded.exp * 1000;
    } catch {
      return true;
    }
  }
}

문서 발급 구현

// src/documents.ts
export interface BirthCertificateData {
  fullName: string;
  fullNameEn?: string;
  dateOfBirth: string;
  placeOfBirth: {
    city: string;
    country: string;
    hospital?: string;
  };
  gender: 'M' | 'F' | 'X';
  parents: Array<{
    relation: 'FATHER' | 'MOTHER' | 'GUARDIAN';
    fullName: string;
    dateOfBirth: string;
    nationalID?: string;
  }>;
  birthWeight?: number;
  birthLength?: number;
}

export interface Document {
  documentId: string;
  documentType: string;
  status: 'ACTIVE' | 'REVOKED' | 'EXPIRED';
  issueDate: string;
  expiryDate?: string;
  data: any;
}

export class DocumentService {
  constructor(private client: WIAPublicDocumentClient) {}

  async createBirthCertificate(
    data: BirthCertificateData
  ): Promise {
    const response = await this.client['client'].post(
      '/documents/birth-certificates',
      data
    );
    return response.data;
  }

  async getDocument(documentId: string): Promise {
    const response = await this.client['client'].get(
      `/documents/${documentId}`
    );
    return response.data;
  }

  async listDocuments(params?: {
    type?: string;
    status?: string;
    limit?: number;
    cursor?: string;
  }): Promise<{
    data: Document[];
    pagination: {
      nextCursor?: string;
      prevCursor?: string;
      hasMore: boolean;
    };
  }> {
    const response = await this.client['client'].get('/documents', {
      params
    });
    return response.data;
  }

  async downloadPDF(documentId: string): Promise {
    const response = await this.client['client'].get(
      `/documents/${documentId}/pdf`,
      { responseType: 'blob' }
    );
    return response.data;
  }

  async verifyDocument(documentId: string): Promise<{
    valid: boolean;
    details: {
      signatureValid: boolean;
      notExpired: boolean;
      notRevoked: boolean;
      issuerTrusted: boolean;
    };
  }> {
    const response = await this.client['client'].post(
      `/documents/${documentId}/verify`
    );
    return response.data;
  }
}

// 사용 예시
async function main() {
  const client = new WIAPublicDocumentClient({
    baseURL: 'https://api.wia-social.org/v1'
  });

  await client.login('officer@seoul.go.kr', 'secure_password');

  const docService = new DocumentService(client);

  // 출생증명서 발급
  const birthCert = await docService.createBirthCertificate({
    fullName: '홍길동',
    fullNameEn: 'Hong Gildong',
    dateOfBirth: '2025-01-10',
    placeOfBirth: {
      city: 'Seoul',
      country: 'KR',
      hospital: '서울대학교병원'
    },
    gender: 'M',
    parents: [
      {
        relation: 'FATHER',
        fullName: '홍만석',
        dateOfBirth: '1990-05-20'
      },
      {
        relation: 'MOTHER',
        fullName: '김영희',
        dateOfBirth: '1992-03-15'
      }
    ]
  });

  console.log('문서 발급 완료:', birthCert.documentId);

  // PDF 다운로드
  const pdfBlob = await docService.downloadPDF(birthCert.documentId);
  // 파일로 저장...
}

4.2 Python SDK 구현

Python은 정부 기관의 백엔드 시스템과 데이터 분석 작업에 널리 사용됩니다. 다음은 Python용 WIA-SOCIAL SDK 구현입니다.

Python 클라이언트

"""
WIA-SOCIAL Public Document Python SDK
"""
import requests
from typing import Optional, Dict, List, Any
from datetime import datetime, timedelta
import jwt
from dataclasses import dataclass
from enum import Enum

class DocumentType(Enum):
    BIRTH_CERTIFICATE = "BIRTH_CERTIFICATE"
    DRIVERS_LICENSE = "DRIVERS_LICENSE"
    PASSPORT = "PASSPORT"
    MARRIAGE_CERTIFICATE = "MARRIAGE_CERTIFICATE"

class DocumentStatus(Enum):
    ACTIVE = "ACTIVE"
    REVOKED = "REVOKED"
    EXPIRED = "EXPIRED"

@dataclass
class WIAConfig:
    base_url: str = "https://api.wia-social.org/v1"
    api_key: Optional[str] = None
    timeout: int = 30

class WIAPublicDocumentClient:
    def __init__(self, config: WIAConfig):
        self.config = config
        self.session = requests.Session()
        self.session.headers.update({
            'Content-Type': 'application/json',
            'User-Agent': 'WIA-SDK-Python/1.0.0'
        })
        self.access_token: Optional[str] = None
        self.refresh_token: Optional[str] = None

    def login(self, email: str, password: str) -> None:
        """사용자 로그인 및 토큰 획득"""
        response = self.session.post(
            f"{self.config.base_url}/auth/login",
            json={'email': email, 'password': password},
            timeout=self.config.timeout
        )
        response.raise_for_status()

        data = response.json()
        self.access_token = data['accessToken']
        self.refresh_token = data['refreshToken']
        self.session.headers['Authorization'] = f"Bearer {self.access_token}"

    def _is_token_expired(self) -> bool:
        """토큰 만료 여부 확인"""
        if not self.access_token:
            return True

        try:
            payload = jwt.decode(
                self.access_token,
                options={"verify_signature": False}
            )
            exp_timestamp = payload.get('exp', 0)
            return datetime.now().timestamp() >= exp_timestamp
        except:
            return True

    def _refresh_access_token(self) -> None:
        """액세스 토큰 갱신"""
        if not self.refresh_token:
            raise ValueError("No refresh token available")

        response = self.session.post(
            f"{self.config.base_url}/auth/refresh",
            json={'refreshToken': self.refresh_token},
            timeout=self.config.timeout
        )
        response.raise_for_status()

        data = response.json()
        self.access_token = data['accessToken']
        self.session.headers['Authorization'] = f"Bearer {self.access_token}"

    def create_birth_certificate(self, data: Dict[str, Any]) -> Dict[str, Any]:
        """출생증명서 발급"""
        if self._is_token_expired():
            self._refresh_access_token()

        response = self.session.post(
            f"{self.config.base_url}/documents/birth-certificates",
            json=data,
            timeout=self.config.timeout
        )
        response.raise_for_status()
        return response.json()

    def get_document(self, document_id: str) -> Dict[str, Any]:
        """문서 조회"""
        if self._is_token_expired():
            self._refresh_access_token()

        response = self.session.get(
            f"{self.config.base_url}/documents/{document_id}",
            timeout=self.config.timeout
        )
        response.raise_for_status()
        return response.json()

    def list_documents(
        self,
        doc_type: Optional[str] = None,
        status: Optional[str] = None,
        limit: int = 20,
        cursor: Optional[str] = None
    ) -> Dict[str, Any]:
        """문서 목록 조회"""
        if self._is_token_expired():
            self._refresh_access_token()

        params = {'limit': limit}
        if doc_type:
            params['type'] = doc_type
        if status:
            params['status'] = status
        if cursor:
            params['cursor'] = cursor

        response = self.session.get(
            f"{self.config.base_url}/documents",
            params=params,
            timeout=self.config.timeout
        )
        response.raise_for_status()
        return response.json()

    def download_pdf(self, document_id: str) -> bytes:
        """PDF 다운로드"""
        if self._is_token_expired():
            self._refresh_access_token()

        response = self.session.get(
            f"{self.config.base_url}/documents/{document_id}/pdf",
            timeout=self.config.timeout
        )
        response.raise_for_status()
        return response.content

    def verify_document(self, document_id: str) -> Dict[str, Any]:
        """문서 검증"""
        response = self.session.post(
            f"{self.config.base_url}/documents/{document_id}/verify",
            timeout=self.config.timeout
        )
        response.raise_for_status()
        return response.json()

# 사용 예시
if __name__ == "__main__":
    # 클라이언트 초기화
    config = WIAConfig(base_url="https://api.wia-social.org/v1")
    client = WIAPublicDocumentClient(config)

    # 로그인
    client.login("officer@seoul.go.kr", "secure_password")

    # 출생증명서 발급
    birth_data = {
        "fullName": "홍길동",
        "fullNameEn": "Hong Gildong",
        "dateOfBirth": "2025-01-10",
        "placeOfBirth": {
            "city": "Seoul",
            "country": "KR",
            "hospital": "서울대학교병원"
        },
        "gender": "M",
        "parents": [
            {
                "relation": "FATHER",
                "fullName": "홍만석",
                "dateOfBirth": "1990-05-20"
            },
            {
                "relation": "MOTHER",
                "fullName": "김영희",
                "dateOfBirth": "1992-03-15"
            }
        ]
    }

    document = client.create_birth_certificate(birth_data)
    print(f"문서 발급 완료: {document['documentId']}")

    # PDF 다운로드
    pdf_bytes = client.download_pdf(document['documentId'])
    with open(f"{document['documentId']}.pdf", "wb") as f:
        f.write(pdf_bytes)

    # 문서 검증
    verification = client.verify_document(document['documentId'])
    print(f"검증 결과: {verification['valid']}")

4.3 Java SDK 구현

Java는 대규모 정부 시스템의 백엔드 구현에 널리 사용됩니다. Spring Boot와 통합 가능한 WIA-SOCIAL Java SDK입니다.

Java 클라이언트 (OkHttp 사용)

package org.wia.social.client;

import okhttp3.*;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.JsonNode;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

public class WIAPublicDocumentClient {
    private final String baseUrl;
    private final OkHttpClient httpClient;
    private final ObjectMapper objectMapper;
    private String accessToken;
    private String refreshToken;

    public WIAPublicDocumentClient(String baseUrl) {
        this.baseUrl = baseUrl;
        this.httpClient = new OkHttpClient.Builder()
            .connectTimeout(30, TimeUnit.SECONDS)
            .readTimeout(30, TimeUnit.SECONDS)
            .writeTimeout(30, TimeUnit.SECONDS)
            .addInterceptor(this::addAuthHeader)
            .authenticator(this::refreshTokenOnUnauthorized)
            .build();
        this.objectMapper = new ObjectMapper();
    }

    private Response addAuthHeader(Interceptor.Chain chain) throws IOException {
        Request original = chain.request();

        if (accessToken == null) {
            return chain.proceed(original);
        }

        Request authorized = original.newBuilder()
            .header("Authorization", "Bearer " + accessToken)
            .header("User-Agent", "WIA-SDK-Java/1.0.0")
            .build();

        return chain.proceed(authorized);
    }

    private Request refreshTokenOnUnauthorized(
        Route route,
        Response response
    ) throws IOException {
        if (response.code() != 401 || refreshToken == null) {
            return null;
        }

        synchronized (this) {
            // 토큰 갱신
            refreshAccessToken();

            // 원래 요청 재시도
            return response.request().newBuilder()
                .header("Authorization", "Bearer " + accessToken)
                .build();
        }
    }

    public void login(String email, String password) throws IOException {
        JsonNode credentials = objectMapper.createObjectNode()
            .put("email", email)
            .put("password", password);

        RequestBody body = RequestBody.create(
            credentials.toString(),
            MediaType.parse("application/json")
        );

        Request request = new Request.Builder()
            .url(baseUrl + "/auth/login")
            .post(body)
            .build();

        try (Response response = httpClient.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                throw new IOException("Login failed: " + response);
            }

            JsonNode data = objectMapper.readTree(response.body().string());
            this.accessToken = data.get("accessToken").asText();
            this.refreshToken = data.get("refreshToken").asText();
        }
    }

    private void refreshAccessToken() throws IOException {
        JsonNode body = objectMapper.createObjectNode()
            .put("refreshToken", refreshToken);

        RequestBody requestBody = RequestBody.create(
            body.toString(),
            MediaType.parse("application/json")
        );

        Request request = new Request.Builder()
            .url(baseUrl + "/auth/refresh")
            .post(requestBody)
            .build();

        try (Response response = httpClient.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                throw new IOException("Token refresh failed");
            }

            JsonNode data = objectMapper.readTree(response.body().string());
            this.accessToken = data.get("accessToken").asText();
        }
    }

    public JsonNode createBirthCertificate(JsonNode data) throws IOException {
        RequestBody body = RequestBody.create(
            data.toString(),
            MediaType.parse("application/json")
        );

        Request request = new Request.Builder()
            .url(baseUrl + "/documents/birth-certificates")
            .post(body)
            .build();

        try (Response response = httpClient.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                throw new IOException("Failed to create document: " + response);
            }

            return objectMapper.readTree(response.body().string());
        }
    }

    public JsonNode getDocument(String documentId) throws IOException {
        Request request = new Request.Builder()
            .url(baseUrl + "/documents/" + documentId)
            .get()
            .build();

        try (Response response = httpClient.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                throw new IOException("Failed to get document: " + response);
            }

            return objectMapper.readTree(response.body().string());
        }
    }

    public byte[] downloadPDF(String documentId) throws IOException {
        Request request = new Request.Builder()
            .url(baseUrl + "/documents/" + documentId + "/pdf")
            .get()
            .build();

        try (Response response = httpClient.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                throw new IOException("Failed to download PDF: " + response);
            }

            return response.body().bytes();
        }
    }
}

// 사용 예시
public class Main {
    public static void main(String[] args) throws IOException {
        WIAPublicDocumentClient client = new WIAPublicDocumentClient(
            "https://api.wia-social.org/v1"
        );

        client.login("officer@seoul.go.kr", "secure_password");

        ObjectMapper mapper = new ObjectMapper();
        JsonNode birthData = mapper.createObjectNode()
            .put("fullName", "홍길동")
            .put("fullNameEn", "Hong Gildong")
            .put("dateOfBirth", "2025-01-10")
            .put("gender", "M");

        JsonNode document = client.createBirthCertificate(birthData);
        System.out.println("문서 발급 완료: " +
            document.get("documentId").asText());
    }
}

4.4 통합 패턴 및 모범 사례

HTTP 상태 코드 및 재시도 전략

견고한 애플리케이션은 다양한 오류 상황을 우아하게 처리해야 합니다. 네트워크 실패, 속도 제한, 일시적인 서비스 불가 등 모두 적절한 처리 전략이 필요합니다.

HTTP 상태 코드 의미 재시도 전략 필요한 조치
400 Bad Request 잘못된 요청 형식 재시도 안함 요청 매개변수 수정
401 Unauthorized 인증 실패 재시도 안함 액세스 토큰 갱신, 재인증
403 Forbidden 권한 부족 재시도 안함 적절한 권한 요청
404 Not Found 리소스가 존재하지 않음 재시도 안함 문서 ID 또는 엔드포인트 확인
429 Too Many Requests 속도 제한 초과 백오프로 재시도 Retry-After 헤더 준수
500 Internal Server Error 서버 오류 백오프로 재시도 지속되면 보고
503 Service Unavailable 일시적 불가 백오프로 재시도 서킷 브레이커 구현
504 Gateway Timeout 업스트림 타임아웃 백오프로 재시도 클라이언트 타임아웃 증가 고려

통합 패턴

패턴 설명 사용 시나리오
Retry with Exponential Backoff 실패 시 지수적으로 증가하는 간격으로 재시도 일시적 네트워크 오류, 서버 과부하
Circuit Breaker 연속 실패 시 요청 차단, 일정 시간 후 재시도 외부 서비스 장애 시 빠른 실패
Request Caching 동일 요청의 결과를 캐싱하여 재사용 자주 조회되는 공개 문서
Batch Operations 여러 작업을 하나의 요청으로 묶음 대량 문서 발급, 검증
Webhook Integration 이벤트 발생 시 자동 알림 문서 발급 완료, 만료 임박

요약

이 장에서는 TypeScript, Python, Java로 WIA-SOCIAL API를 구현하는 방법을 살펴보았습니다. 각 SDK는 인증, 토큰 관리, 오류 처리, 재시도 로직 등을 포함하여 프로덕션 환경에서 사용 가능한 수준의 구현을 제공합니다. 다음 장에서는 문서 교환을 위한 프로토콜 사양을 다룹니다.

🤔 복습 질문

  1. JWT 토큰 갱신 메커니즘이 각 언어의 SDK에서 어떻게 구현되는지 비교하세요.
  2. Circuit Breaker 패턴이 필요한 이유와 구현 방법을 설명하세요.
  3. TypeScript의 Axios Interceptor가 어떤 문제를 해결하는지 설명하세요.
  4. 대량의 문서를 한 번에 발급해야 할 때 어떤 최적화 전략을 사용할 수 있나요?
  5. SDK에서 오류 처리를 일관되게 수행하는 것이 왜 중요한가요?

한국 일반 인프라 매핑 (제4장)

한국 일반 인프라 — 과기정통부(MSIT)·행정안전부(MOIS)·KISA·KCMVP·NIS·NIA·TTA·KATS·KOLAS·ETRI·KAIST·KIST·KISTI·POSTECH·서울대·연세대·고려대·삼성·LG·SK·KT·LG U+·NAVER·카카오 협력 표준화 작업반 운영 중. 「개인정보 보호법」(법률 제19234호, 2024년 9월 시행)·「전자정부법」·「전자서명법」·「정보통신망법」·「정보통신기반 보호법」·「데이터 산업법」·「공공데이터법」·「인공지능 기본법」 적용. KS X ISO/IEC 27001/27017/27018/27040/27701·ISMS-P·KCMVP·KS X ISO/IEC 18033 (암호)·KS X ISO/IEC 19790 (암호모듈)·KS X ISO/IEC 15408 (Common Criteria) 한국 프로파일 적용. NIA「ICT 표준화 추진체계 운영」·KISA「개인정보보호 종합 포털」·MSIT「K-디지털 2030」 로드맵 운영 중.

한국 디지털 전환·표준화 상세 매핑

한국의 디지털 전환과 표준화는 다음 협력 체계로 운영된다. 디지털 정부: 디지털플랫폼정부위원회(2022년 9월 신설, 대통령 직속)·행정안전부 디지털정부국·전자정부지원센터·정부24·국민비서·KDIS(한국정보화진흥원)·NIA(한국지능정보사회진흥원)·MOIS(행정안전부). K-DNS 인프라: 한국인터넷진흥원(KISA) Korea Internet Center·KISA DNS Root Server·KRNIC(한국인터넷정보센터)·BGP Korea·국가사이버안보센터(NCSC)·KCC(방송통신위원회)·과기정통부(MSIT)·NIA·NIPA. 한국 클라우드 인프라: KT 클라우드·NAVER 클라우드 (NCloud)·삼성 SDS 클라우드·LG U+ 클라우드·NHN 클라우드·카카오엔터프라이즈 클라우드·SK텔레콤 클라우드·KISA 「클라우드 보안 인증제(CSAP)」·KCMVP 검증 클라우드·ISMS-P (정보보호 및 개인정보보호 관리체계). 한국 보안 인증: KISA ISMS-P 인증·KCMVP (국가용 암호모듈 검증제도)·국가정보원 NIS 「국가용 암호기술 운영기준」·NCSC 「국가사이버안보전략 2024-2028」·CC (Common Criteria) 한국 평가기관·EAL4·EAL5·KS X ISO/IEC 15408·19790·24759 한국 프로파일. 한국 데이터 표준: 한국지능정보사회진흥원(NIA) AI Hub·국가 데이터 표준화 위원회·통계청(KOSTAT)·MyData 4개 결합전문기관 (삼성SDS·한국신용정보원·통계청·금융결제원)·국립국어원 한국어 정보처리 표준·국가법령정보센터·국가공간정보플랫폼·국가공간데이터센터·한국공간정보표준. 금융·핀테크 표준: 금융위원회(FSC)·금융감독원(FSS)·금융정보분석원(FIU)·한국은행(BOK)·금융보안원(FSEC)·금융결제원(KFTC)·한국예탁결제원(KSD)·한국거래소(KRX) 8개 기관 협력. 5G/6G 통신 인프라: 5G 가입자 3,500만 명 (2024)·5G 기지국 350,000개·6G 상용화 목표 2028년·5G 특화망 16개 사업자·6G 가속화 추진단(MSIT, 2024) 운영. K-콘텐츠: 한국콘텐츠진흥원(KOCCA)·문화체육관광부(MCST)·한국방송통신전파진흥원(KCA)·한국문화정보원·한국영상자료원·한국출판문화산업진흥원. 「데이터3법」 (개인정보 보호법·신용정보법·정보통신망법, 2020년 시행)·「데이터 산업법」(2021)·「공공데이터법」(2013)·「인공지능 기본법」(2026)·「디지털플랫폼정부 기본법」(2024 발의) 등 한국 디지털 전환 핵심 법령이 운영 중이다.

한국 산업·연구·교육 인프라 종합 매핑

한국의 산업 생태계와 표준화 체계는 다음 핵심 인프라로 구성된다. 한국 5대 그룹: 삼성·현대자동차·LG·SK·롯데. 각 그룹별 표준화 위원회와 ISO/IEC TC 한국 간사 활동. 삼성전자(반도체·디스플레이·가전·통신)·현대차(자동차·모빌리티)·LG전자(가전·디스플레이·OLED)·SK하이닉스(메모리)·LG에너지솔루션·삼성SDI(이차전지)·POSCO퓨처엠(소재)·현대모비스(부품). 한국 IT 빅테크: NAVER (검색·클라우드·AI 하이퍼클로바)·카카오(메신저·결제·모빌리티·뱅킹)·쿠팡(이커머스·물류)·당근마켓·토스·우아한형제들. 한국 통신3사: SK텔레콤·KT·LG U+. 5G·5G 특화망·B2B 클라우드·AI 사업 운영. 한국 7대 거점 대학: 서울대·KAIST·POSTECH·연세대·고려대·UNIST·DGIST·GIST. 모두 표준화 R&D 거점이며 ISO/IEC/IEEE 한국 의장 활동 중. 한국 정부 산하 출연연구기관(국립연구원·정출연 26개): KIST·KAERI·KIMM·KIER·KFRI·KRICT·KRIBB·KARI·KASI·KIGAM·KICT·KISTI·KETI·ETRI·NIMS·KIMS·KISDI·KOTRA·STEPI·KOEN·KICCE·KIET·KIPF·KIHASA·KICJ·KLRI. 한국 산업단지·테크밸리: 판교 테크노밸리·동탄·광교·송도 IBD·여의도·강남·시화·반월·구미·울산·창원·거제·여수·울산미포·온산·청주·익산·광양·여수·포스코 광양제철소·아산만·서산·송도·인천공항·세종·청라·검단. 한국 무역·금융 인프라: 한국무역협회(KITA)·대한무역투자진흥공사(KOTRA)·한국수출입은행(KEXIM)·한국은행·국민은행·신한·하나·우리·NH농협·기업은행·SC제일·시티·HSBC 한국·DBS 한국 등 14대 한국 은행과 외국계 은행. 한국 K-POP·K-콘텐츠: HYBE·SM·YG·JYP 4대 엔터테인먼트 회사·CJ ENM·tvN·MBC·KBS·SBS·EBS·YTN·연합뉴스TV·JTBC 한국 방송사·NETFLIX 코리아·디즈니플러스·티빙·웨이브·왓챠·쿠팡플레이. 한국 게임 산업: 넥슨·엔씨소프트·크래프톤·넷마블·카카오게임즈·펄어비스·컴투스·게임빌·NHN·스마일게이트·웹젠. 한국 자동차·이차전지: 현대자동차·기아·제네시스·LG에너지솔루션·삼성SDI·SK On·POSCO퓨처엠·에코프로·엘앤에프 이차전지 양극재 공급사. 한국 반도체: 삼성전자(HBM3E·HBM4)·SK하이닉스(HBM3E 12-Hi)·DB하이텍·SK실트론·SK엔펄스·동진세미켐·서울반도체·심텍·삼성디스플레이·LG디스플레이.

한국 표준화 인프라 종합 매핑

한국의 산업·기술 표준화는 다음 협력 체계를 통해 운영된다. 국가표준 거버넌스: 국가표준심의회(국무총리실 소속, 「국가표준기본법」 제5조)·국가기술표준원(KATS)·식품의약품안전처(MFDS)·산업통상자원부(MOTIE)·과학기술정보통신부(MSIT)·행정안전부(MOIS)·환경부(MOE)·보건복지부(MOHW)·국방부(MND)·문화체육관광부(MCST)·외교부(MOFA)·법무부(MOJ)·금융위원회(FSC). 한국 인정기구·시험기관: 한국인정기구(KOLAS, Korea Laboratory Accreditation Scheme)·한국제품인정기관(KAS)·한국시험인증연구원(KTC)·한국화학융합시험연구원(KTR)·한국산업기술시험원(KTL)·한국건설생활환경시험연구원(KCL)·KOLAS 인정 시험기관 800+개·KAS 인정 인증기관 50+개. 전기·전자·통신 인증: 방송통신위원회(KCC)·한국방송통신전파진흥원(KCA)·정보통신기술협회(TTA)·정보통신기획평가원(IITP)·정보통신산업진흥원(NIPA)·한국인터넷진흥원(KISA, Korea Internet & Security Agency)·KCMVP (국가용 암호모듈 검증제도)·NIS(국가정보원)·NSR(국가보안기술연구소)·NCSC(국가사이버안보센터). 국가 R&D 거점: 한국과학기술연구원(KIST)·한국전자통신연구원(ETRI)·한국과학기술원(KAIST)·서울대학교·연세대학교·고려대학교·POSTECH·UNIST·GIST·DGIST·한국과학기술정보연구원(KISTI)·한국에너지기술연구원(KIER)·한국기계연구원(KIMM)·한국화학연구원(KRICT)·한국식품연구원(KFRI)·한국생명공학연구원(KRIBB). 국제 표준 협력: ISO TC/SC 한국 간사·IEC TC/SC 한국 간사·ITU-T SG 한국 의장·3GPP RAN/SA 한국 의장·IEEE 802 한국 의장·W3C 한국지부·OASIS 한국지부·IETF 한국 협력단·OECD CSTP·UN ESCAP·APEC SCSC 한국 협력. 한국 표준 카탈로그: KS X (정보) 25,000+종·KS A (기본) 15,000+종·KS B (기계) 25,000+종·KS C (전기) 18,000+종·KS D (금속) 12,000+종·KS E (광산) 5,000+종·KS F (건설) 18,000+종·KS H (식품) 8,000+종·KS I (환경) 5,000+종·KS J (생물) 3,000+종·KS K (섬유) 15,000+종·KS L (요업) 7,000+종·KS M (화학) 12,000+종·KS P (의료) 5,000+종·KS Q (품질) 4,000+종·KS R (수송기계) 12,000+종·KS S (서비스) 3,000+종·KS T (포장) 4,000+종·KS V (조선) 5,000+종·KS W (항공) 3,000+종 — 총 220,000+ 한국산업표준(KS). 「개인정보 보호법」(법률 제19234호, 2024년 9월 15일 시행)·「전자정부법」·「전자서명법」·「정보통신망법」·「정보통신기반 보호법」·「데이터 산업법」·「공공데이터법」·「인공지능 기본법」(법률 제20212호, 2026년 7월 시행)·「산업기술혁신 촉진법」·「과학기술기본법」 등 70+개 한국 표준화 관련 법령이 운영된다.