MPC 서비스 가이드
MPC는 Multi-Party Computation 기반의 분산 키 관리 및 서명 서비스입니다. 개인키를 단일 장소에 보관하지 않고, 여러 노드에 분산하여 보안성을 극대화합니다. 이 문서에서는 MPC의 구성 요소와 연동 방식에 대해 설명합니다.
각 연동 방식별 상세 사용법과 코드 예시는 별도 문서를 참고하세요.
| 연동 방식 | 사용법 문서 |
|---|---|
| Client Node (서버 사이드) | Client Node API 가이드 |
| WASM (웹) | 자세히 안내드리기 위해 별도로 제공되오니 문의(abcwaas@ahnlab.io)해주시기 바랍니다. |
| Mobile SDK (Android/iOS) | Mobile SDK 가이드 |
아키텍처 개요
MPC는 사용 환경에 따라 두 가지 연동 방식을 제공합니다.
방식 A: Client Node 사용 (서버 사이드)
클라이언트에서 WASM이나 Mobile SDK를 사용하지 않는 경우, MPC Client Node(Docker)를 고객사 환경에 설치하여 서버 사이드에서 MPC 기능을 사용합니다. 고객사 백엔드에서 Client Node의 REST API를 호출하는 방식입니다.
이 방식은 키쉐어 관리를 서버에서 처리하고자 하는 경우에 적합합니다. 사용자 단말에 SDK를 설치하지 않고, 고객사 백엔드에서 직접 키 생성과 서명을 수행하는 서비스에서 사용됩니다.
방식 B: WASM / Mobile SDK 사용 (클라이언트 사이드)
클라이언트에서 WASM(웹) 또는 Mobile SDK(Android/iOS)를 사용하는 경우, Client Node 없이 클라이언트에서 직접 MPC Node와 통신하여 서명 및 키 생성을 수행합니다.
이 방식은 사용자 단말에서 직접 서명을 수행하는 경우에 적합합니다. 지갑 앱, DApp 브라우저 등 사용자가 직접 트랜잭션을 승인하고 서명하는 서비스에서 주로 사용됩니다. 키쉐어가 서버를 거치지 않고 클라이언트에서 직접 처리되므로, 서버 침해에 의한 키쉐어 유출 위험이 없습니다. 고객사 백엔드는 인증 토큰만 발급하여 클라이언트에 전달하면 됩니다.
구성 요소
| 구성 요소 | 운영 주체 | 설명 |
|---|---|---|
| Client Node | 고객사 | MPC 노드와의 통신을 조율하는 게이트웨이. Docker 이미지로 제공. 방식 A에서 사용 |
| MPC Node 1 | ABC | 분산 키 생성 및 서명을 수행하는 MPC 연산 노드 |
| MPC Node 2 | 제3자 기관 | 키 조각을 독립적으로 관리하는 MPC 연산 노드. ABC와 별도의 기관이 운영 |
| Mobile SDK | 고객사 앱 | Android/iOS 네이티브 앱에서 MPC 기능 사용. 방식 B |
| WASM | 고객사 웹 | 웹 브라우저에서 MPC 기능 사용. 방식 B |
MPC Node 1과 Node 2는 서로 다른 기관이 독립적으로 운영합니다. 이를 통해 단일 기관의 침해만으로는 개인키가 노출되지 않는 구조를 보장합니다.
핵심 원칙
- 개인키 미노출: 어떤 단일 노드도 완전한 개인키를 보유하지 않습니다. MPC 프로토콜의 어떤 단계에서도 완전한 개인키가 단일 장소에 존재하지 않습니다.
- 분산 서명: 서명은 MPC Node 간 다중 라운드 프로토콜을 통해 수행됩니다. 서명 과정에서도 개인키를 복원하지 않고 분산된 상태로 서명을 생성합니다.
- 클라이언트 측 암호화: 키쉐어는 사용자 비밀번호로 암호화되어 클라이언트에 저장됩니다. 서버는 암호화된 상태만 처리하며, 평문 키쉐어에 접근할 수 없습니다.
- 독립 운영: MPC Node 1과 Node 2는 서로 다른 기관이 운영하므로, 한쪽이 침해되더라도 나머지 노드만으로는 서명이나 키 복원이 불가능합니다.
주요 기능
MPC는 다음 기능을 제공합니다. 모든 기능은 Client Node, WASM, Mobile SDK에서 동일하게 사용할 수 있습니다.
키쉐어 생성
MPC 서비스를 사용하기 위해 가장 먼저 수행해야 하는 단계입니다. 키쉐어 생성을 요청하면 MPC Node 간 다중 라운드 프로토콜이 실행되어, 완전한 개인키를 어디에도 노출하지 않은 채 분산된 키 조각이 생성됩니다. 생성 시 사용자가 설정한 비밀번호로 키쉐어가 암호화되며, 다음 값이 반환됩니다.
| 반환값 | 설명 |
|---|---|
keyId | 키 식별자. 서명 및 키 관리 시 사용됩니다. |
encryptedShare | 암호화된 키쉐어. 서명의 핵심 데이터입니다. |
secretStore | 키쉐어 복호화에 필요한 시크릿 데이터입니다. |
curve | 사용된 curve (secp256k1 또는 ed25519) |
키쉐어 복구
기기 변경, 앱 재설치, 데이터 유실 등으로 로컬에 저장된 키쉐어를 사용할 수 없게 된 경우, 서버에 등록된 키 정보를 기반으로 키쉐어를 복구할 수 있습니다. 복구 과정에서도 키 생성과 동일하게 MPC 프로토콜이 실행되어 새로운 키쉐어가 안전하게 생성됩니다.
복구 시 새로운 keyId가 발급되지만, 기존 키와 동일한 공개키를 사용하므로 블록체인 상의 주소나 자산에는 영향이 없습니다. 복구된 키쉐어로 기존과 동일하게 서명을 수행할 수 있습니다.
서명
키쉐어를 사용하여 메시지에 서명합니다. 서명 과정에서도 개인키는 복원되지 않으며, MPC Node 간 다중 라운드 프로토콜을 통해 분산된 상태로 서명이 생성됩니다. 서명 결과는 일반적인 ECDSA/EdDSA 서명과 동일한 형식이므로, 블록체인 네트워크에 그대로 제출할 수 있습니다.
curve에 따라 권장하는 서명 방식이 다릅니다.
| Curve | 권장 서명 방식 | 설명 |
|---|---|---|
| secp256k1 | MTA 서명 | Multiplicative-to-Additive 프로토콜 기반의 보안 강화 서명 |
| ed25519 | 기본 서명 | 표준 EdDSA 서명 |
검증
서명을 수행하기 전에, 키쉐어와 비밀번호가 유효한지 사전에 검증할 수 있습니다. 잘못된 비밀번호나 손상된 키쉐어로 서명을 시도하면 MPC 프로토콜이 실패하게 되므로, 사전 검증을 통해 불필요한 실패를 방지하는 것을 권장합니다.
- 비밀번호 검증: 키쉐어 생성 시 사용한 비밀번호가 올바른지 확인합니다. 사용자가 비밀번호를 잊어버렸거나 잘못 입력하는 경우를 사전에 감지할 수 있습니다.
- 키쉐어 검증: 키쉐어 데이터의 무결성을 확인합니다. 저장 과정에서 데이터가 손상되지 않았는지, 비밀번호로 정상적으로 복호화할 수 있는지 검증합니다.
키쉐어 보관 시 주의사항
키쉐어 생성 시 반환되는 keyId, encryptedShare, secretStore 정보는 서명에 필수적인 중요 데이터입니다. 사용 방식에 따라 다음 사항에 유의해야 합니다.
방식 A — Client Node (서버 사이드)
키 생성 시 반환되는 정보를 고객사 서버에서 반드시 암호화하여 보관해야 합니다. 해당 정보가 유출될 경우 보안 위험이 발생할 수 있으므로, 저장 및 접근 권한 관리에 각별히 주의해야 합니다.
방식 B — Mobile SDK (클라이언트 사이드)
SDK 자체적으로 모바일 기기의 보안 영역(Android Keystore, iOS Keychain)에 키쉐어를 저장하는 기능을 제공합니다. SDK가 제공하는 자동 저장 기능을 사용하지 않는 경우에도, 반드시 모바일 기기의 보안 영역에 저장하여 사용하는 것을 권장합니다.
방식 B — WASM (클라이언트 사이드)
웹 브라우저 환경에서는 키쉐어가 브라우저에 저장되므로, 보안에 각별히 신경을 써야 합니다. 암호화 저장 및 접근 제한 등 추가적인 보안 조치를 적용하는 것을 권장합니다.
MPC 통신 구조
MPC는 2-of-3 구조를 사용합니다. 세 참여자(클라이언트, MPC Node 1, MPC Node 2)가 각각 키 조각을 보유하며, 이 중 2개의 키 조각만 있으면 서명을 수행할 수 있습니다.
일반적인 사용에서는 클라이언트와 MPC Node 1이 키 생성 및 서명에 참여합니다. MPC Node 2는 복구를 위한 백업 역할을 하며, 클라이언트가 키쉐어를 분실한 경우 복구에 사용됩니다.
| 참여자 | 역할 |
|---|---|
| 클라이언트 | 키 조각 보유. 키 생성 및 서명 시 MPC Node 1과 함께 참여 |
| MPC Node 1 (ABC) | 키 조각 보유. 키 생성 및 서명 시 클라이언트와 함께 참여 |
| MPC Node 2 (제3자 기관) | 키 조각 보유. 클라이언트 키쉐어 분실 시 복구에 사용 |
3자 통신 흐름
키 생성, 서명, 복구 등 모든 MPC 연산은 참여자 간 다중 라운드 통신을 통해 이루어집니다. 각 참여자는 자신의 키 조각만 보유한 채 통신하며, 완전한 개인키는 어디에도 존재하지 않습니다.
키 생성 및 복구 시에는 클라이언트, MPC Node 1, MPC Node 2 세 참여자가 모두 통신에 참여하여 각각의 키 조각을 생성합니다.
서명 시에는 클라이언트와 MPC Node 1만 참여합니다 (2-of-3). MPC Node 2는 서명에 참여하지 않습니다.
Client Node 운영 개요
MPC Client Node는 Docker 이미지로 제공됩니다. 고객사 백엔드 환경에 배포하여 MPC 노드와의 통신을 담당합니다. 고객사는 Docker 이미지를 실행하고 환경 변수만 설정하면 바로 사용할 수 있으며, 별도의 빌드나 소스코드 관리가 필요하지 않습니다.
주요 특징
- Docker 기반 배포: 컨테이너 이미지로 제공되어 별도의 빌드 없이 바로 실행 가능합니다. Kubernetes, ECS 등 컨테이너 오케스트레이션 환경에서도 운영할 수 있습니다.
- Stateless 구조: Client Node 자체는 키 데이터를 저장하지 않습니다. 모든 요청은 MPC Node에 위임되므로, 트래픽 증가 시 Client Node 인스턴스를 수평 확장할 수 있습니다.
- Swagger UI 내장: API 문서를 내장하고 있어 별도의 문서 없이 브라우저에서 API를 탐색하고 테스트할 수 있습니다.
- 환경 변수 설정: MPC Node URL, 인증 정보, 앱 서버 URL 등을 환경 변수로 설정합니다. ABC에서 제공하는 인증 정보를 환경 변수에 설정하면 MPC Node와의 연결이 자동으로 구성됩니다.
주요 API
| 기능 | 메서드 | 경로 |
|---|---|---|
| 키쉐어 생성 | POST | /v3/wallet/generate |
| 키쉐어 복구 | POST | /v3/wallet/recover |
| 기본 서명 | POST | /v3/wallet/sign |
| MTA 서명 | POST | /v3/wallet/sign/mta |
| 공개키 조회 | POST | /v3/wallet/publickey |
| 비밀번호 검증 | POST | /v3/wallet/validate/password |
| 키쉐어 검증 | POST | /v3/wallet/validate/share |
| 등록된 키 조회 | GET | /v3/wallet/key |
| 키 등록 | POST | /v3/wallet/key |
운영 시 주의사항
- Client Node는 MPC Node와의 통신을 중계하므로, 네트워크 지연이 낮은 환경에 배치하는 것을 권장합니다. MPC 서명은 다중 라운드 프로토콜로 동작하기 때문에, 네트워크 지연이 서명 소요 시간에 직접적인 영향을 줍니다.
- MPC Node의 URL과 인증 정보는 ABC에서 별도로 제공합니다. 해당 인증 정보는 안전하게 관리해야 하며, 소스코드나 공개 저장소에 포함하지 않도록 주의해야 합니다.
- Client Node는 고객사 백엔드에서만 접근 가능하도록 네트워크 접근 제어를 설정하는 것을 권장합니다.
상세 설정 방법과 Docker 실행 가이드는 Client Node API 가이드를 참고하세요.
보안 참고사항
- 개인키 미노출: MPC 프로토콜의 어떤 단계에서도 완전한 개인키가 단일 장소에 존재하지 않습니다.
- 독립 운영 노드: MPC Node 1(ABC)과 Node 2(제3자 기관)가 독립적으로 운영되어, 단일 기관 침해로는 키가 노출되지 않습니다.
- 클라이언트 측 암호화: 키쉐어는 사용자 비밀번호로 암호화되어 저장됩니다. 서버는 암호화된 데이터만 처리합니다.
- 모바일 보안 저장소: Mobile SDK는 Android Keystore, iOS Keychain을 활용하여 키쉐어를 안전하게 보관하는 기능을 제공합니다.
- 기기 격리: Mobile SDK로 저장된 키쉐어는 해당 기기의 해당 앱에서만 접근 가능하며, 백업이나 기기 이전 시 복원되지 않습니다.
- 동시 서명 제한: MTA 서명은 다중 라운드 프로토콜을 사용하므로, 동일한 키에 대해 동시에 여러 서명 요청을 보내지 않아야 합니다.