# DiCert SDK 개발 문서

> DiCert SDK로 웹 서비스에 공동인증서 선택 창을 붙이는 방법과 옵션, 전달 정보, 서버 처리, 오류 동작을 정리했습니다.

최종 수정: 2026-10-27

## 개요

DiCert는 웹 서비스에서 사용자 PC에 저장된 공동인증서(NPKI, 구 공인인증서)를 불러올 수 있게 해 주는 SDK입니다. 서비스 페이지에 스크립트를 추가하고 `CertModal`을 열면 인증서 선택 창이 나타나고, 사용자가 고른 인증서 정보가 `onConfirm` 콜백으로 전달됩니다.

DiCert가 맡는 부분과 연동 서비스가 구현할 부분은 다음과 같습니다.

| 구분 | 내용 |
| --- | --- |
| DiCert가 제공 | 사용자 PC의 인증서 탐색, 인증서 선택 창, 비밀번호 확인, 선택한 인증서 정보 전달, .p12/.pfx 가져오기와 내보내기 |
| 연동 서비스가 구현 | 전달받은 정보의 서버 전송과 보관, 전자서명, 기관 로그인, 기관 데이터 조회·신고 등 기관별 업무 처리 |

> 사용자 PC에는 DiCert 보안 프로그램(Windows·macOS)이 설치되어 있어야 합니다. 설치되어 있지 않으면 선택 창이 설치 안내를 보여 줍니다.

## 빠른 시작

1. DiCert에 회원가입하고 대시보드에서 서비스 도메인을 등록합니다. `https://`, 경로, 쿼리 없이 호스트 이름만 입력합니다(예: `example.com`, `app.example.com`). 등록한 도메인의 하위 도메인에서도 동작합니다.
2. 실서비스 도메인은 월정기 구독을 시작합니다. 개발 중에는 `localhost`에서 구독 없이 바로 테스트할 수 있습니다.
3. 서비스 페이지에 스크립트를 추가합니다.
4. 버튼 클릭 등에서 `CertModal`을 열고, `onConfirm`에서 전달받은 정보를 서버로 보냅니다.

```html
<script src="https://dicert.di3.kr/sdk/cert-modal.js"></script>
```

```js
const certModal = new CertModal({
  onConfirm: async (payload) => {
    // 비밀번호와 개인키가 들어 있으므로 HTTPS로만 전송합니다
    const res = await fetch('/api/cert/register', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(payload),
    });
    if (!res.ok) throw new Error('등록 실패');
  },
  onCancel: () => {
    // 사용자가 선택 창을 닫았을 때
  },
});

document.getElementById('certButton').addEventListener('click', () => certModal.open());
```

완성된 예제 화면은 [샘플 코드](https://dicert.di3.kr/sdk/sample.html)와 [데모](https://dicert.di3.kr/sdk/demo.html)에서 볼 수 있습니다.

## 동작 방식

1. 서비스 페이지에서 `certModal.open()`을 호출하면 선택 창이 열리고, 사용자 PC의 DiCert 보안 프로그램에 연결합니다.
2. 보안 프로그램은 요청한 사이트가 DiCert에 등록된 도메인인지 확인합니다. 등록 도메인 목록은 DiCert 서버에서 받아 옵니다. 도메인을 새로 등록했다면 반영까지 잠시 걸릴 수 있습니다.
3. 보안 프로그램이 하드디스크와 이동식 저장장치에서 인증서를 찾아 목록을 보여 줍니다.
4. 사용자가 인증서를 고르고 비밀번호를 입력하면, 보안 프로그램이 비밀번호가 맞는지 확인합니다.
5. 확인되면 인증서 정보가 `onConfirm(payload)`로 서비스 페이지에 전달됩니다.

> 인증서와 비밀번호는 DiCert 서버로 전송·보관되지 않습니다. DiCert 서버는 등록된 도메인 목록만 보안 프로그램에 알려 줍니다.

## 옵션과 메서드

| 옵션 | 타입 | 기본값 | 설명 |
| --- | --- | --- | --- |
| `onConfirm` | function(payload) | 필수 | 인증서 선택과 비밀번호 확인이 끝나면 호출됩니다. Promise를 반환해도 됩니다. |
| `onCancel` | function() | 없음 | 사용자가 선택 창을 닫으면 호출됩니다. |
| `certType` | 'all' \| 'personal' \| 'corporate' | 'all' | 'personal'은 개인 인증서(범용개인, 전자거래 서명용 등)만, 'corporate'는 법인·사업자 인증서만 보여 줍니다. |
| `hideExpired` | boolean | false | true이면 만료된 인증서를 목록에서 숨깁니다. false이면 만료 인증서도 구분 표시와 함께 보여 줍니다. |
| `helperUrl` | string | 'http://127.0.0.1:34913' | 보안 프로그램 주소입니다. 일반적으로 바꿀 필요가 없습니다. |

| 메서드 | 설명 |
| --- | --- |
| `open()` | 선택 창을 엽니다. |
| `close()` | 선택 창을 닫습니다. |

```js
// 법인 인증서만, 만료 인증서 숨김 (조달·전자입찰 서비스 예시)
const certModal = new CertModal({
  certType: 'corporate',
  hideExpired: true,
  onConfirm: async (payload) => { /* ... */ },
});
```

## 전달 정보 (payload)

`onConfirm`으로 전달되는 객체의 필드입니다. 파일 데이터는 Base64 문자열입니다.

| 필드 | 타입 | 설명 |
| --- | --- | --- |
| `owner` | string | 인증서 소유자 이름 (Subject CN) |
| `purpose` | string | 용도 (범용개인, 법인, 사업자, 전자거래 서명용 등) |
| `issuer` | string | 발급기관명 |
| `expiry` | string | 만료일 (YYYY-MM-DD) |
| `password` | string | 사용자가 입력한 인증서 비밀번호 |
| `certBase64` | string | 서명용 인증서 파일 (signCert.der) |
| `keyBase64` | string | 서명용 개인키 파일 (signPri.key). 사용자 비밀번호로 보호된 상태 그대로입니다. |
| `kmCertBase64` | string \| null | 암호화용 인증서 (kmCert.der). 없으면 null |
| `kmKeyBase64` | string \| null | 암호화용 개인키 (kmPri.key). 없으면 null |
| `caPubsBase64` | string \| null | CA 인증 체인 (CaPubs). 없으면 null |
| `serialNumber` | string | 인증서 일련번호 (hex) |
| `subjectDN` | string | 전체 Subject DN (예: CN=홍길동,OU=...,O=yessign,C=kr) |
| `issuerDN` | string | 전체 Issuer DN |
| `notBefore` | string | 유효 시작일 (YYYY-MM-DD) |
| `keyUsage` | string[] | 키 용도 (digitalSignature, nonRepudiation 등) |
| `oid` | string[] | 인증서 정책 OID. 범용·금융·조달·행정 용도 구분에 사용 |
| `vid` | string | 가상식별번호 VID (subjectAltName, hex) |
| `fingerprint` | string | SHA-256 지문 (hex) |
| `kmSubjectDN` | string | 암호화용 인증서 Subject DN (암호화용 인증서가 있을 때) |
| `kmKeyUsage` | string[] | 암호화용 인증서 키 용도 (암호화용 인증서가 있을 때) |

기관별로 자주 쓰는 필드는 다음과 같습니다. 실제 요구사항은 각 기관의 연동 규격을 기준으로 확인하세요.

| 활용 예 | 주로 쓰는 필드 |
| --- | --- |
| 홈택스, 정부24 | certBase64, keyBase64, password |
| 나라장터(G2B) | certBase64, keyBase64, kmCertBase64, password |
| 건강보험 EDI | certBase64, keyBase64, kmCertBase64, kmKeyBase64, password |
| 금융·은행·증권 | certBase64, keyBase64, password, oid |
| 인터넷등기소 | certBase64, keyBase64, password, serialNumber |

## 서버에서 처리할 때

payload에는 개인키 파일과 비밀번호가 함께 들어 있습니다. 서버로 보내고 보관하는 방식은 연동 서비스가 정하며, 다음 사항을 권장합니다.

- HTTPS로만 전송하고, 요청 본문을 로그나 오류 리포트에 남기지 않습니다.
- 보관이 필요하면 암호화해서 저장하고 접근 권한을 최소로 제한합니다.
- 비밀번호가 계속 필요하지 않은 업무라면 서명이 끝난 뒤 보관하지 않습니다.
- 필요한 필드만 서버로 보냅니다. 위의 기관별 표를 참고하세요.
- 전자서명과 기관 연동은 서버나 별도 서명 모듈에서 구현합니다. DiCert는 서명을 수행하지 않습니다.

## 오류와 예외 동작

현재 오류는 선택 창 안에서 사용자에게 안내되며, 연동 서비스로 오류 코드를 넘기지 않습니다. 사용자가 창을 닫으면 `onCancel`이 호출됩니다.

| 상황 | 선택 창 동작 |
| --- | --- |
| 보안 프로그램이 설치되지 않았거나 실행 중이 아님 | Windows·macOS 설치 파일 다운로드 안내와 다시 시도 버튼을 보여 줍니다. |
| 등록되지 않은 도메인에서 호출 | 등록되지 않은 사이트라는 안내를 보여 줍니다. 대시보드에서 도메인 등록과 구독 상태를 확인하세요. |
| 인증서를 찾지 못함 | 인증서가 없다는 안내를 보여 줍니다. |
| 비밀번호가 틀림 | 선택 창 안에서 다시 입력하도록 안내합니다. |

> 보안 프로그램이 개인키 형식을 해석하지 못하는 일부 인증서는 비밀번호 확인 없이 전달될 수 있습니다. 서버에서 서명할 때 비밀번호 오류를 처리하도록 구현하세요.

## 지원 범위와 환경

| 항목 | 내용 |
| --- | --- |
| 인증서 위치 | 하드디스크와 USB 등 이동식 저장장치의 NPKI 폴더, 행정전자서명(GPKI)·교육행정전자서명(EPKI) 인증서 폴더 |
| 인증서 파일 | signCert.der·signPri.key 형식, .p12/.pfx 가져오기 |
| 아직 지원하지 않음 | 보안토큰(HSM), 휴대폰 인증서, 간편인증, 금융인증서 |
| Windows | Windows 10 이상(x64), 보안 프로그램 1.1.24 |
| macOS | macOS 10.15 이상(Intel·Apple Silicon), 보안 프로그램 1.2.56 |
| 브라우저 | 최신 버전 브라우저를 권장합니다. |

보안 프로그램은 [DiCert 홈페이지](https://dicert.di3.kr/#install)에서 내려받을 수 있습니다. 사용자는 최초 1회 설치하면 되고, 이후에는 PC에 로그인할 때 자동으로 실행됩니다.

## 요금

- 개발·로컬 환경(`localhost`)은 무료이며 별도 신청이 필요 없습니다.
- 실서비스는 도메인 1개당 월 9,900원(VAT 별도, 실청구 10,890원)이며 월자동결제로 이용하고 언제든 해지할 수 있습니다.
- 결제에 실패하면 7일의 유예 기간 동안 계속 이용할 수 있고, 그 안에 결제되지 않으면 이용이 정지됩니다(이용약관 제6조).
- 해지하면 다음 결제일부터 청구되지 않으며, 이미 결제한 기간까지는 계속 이용할 수 있습니다.

## 관련 자료

- [SDK 스크립트](https://dicert.di3.kr/sdk/cert-modal.js)
- [샘플 코드](https://dicert.di3.kr/sdk/sample.html), [데모](https://dicert.di3.kr/sdk/demo.html)
- [사용 설명서 PDF](https://dicert.di3.kr/downloads/dicert-user-manual.pdf): 회원가입, 도메인 등록, 카드 등록
- [이 문서의 Markdown 버전](https://dicert.di3.kr/docs/sdk.md)
- 문의: support@di3.kr, 031-990-7021
