develicit
← 글 목록으로

휴대폰에 지갑 키를 보관하는 것은 완벽하게 안전할 수 있을까

·읽는 시간 40분

핵심 명제 — "절대적으로 안전한 보관 방식"은 존재하지 않는다. 휴대폰에 지갑 키를 보관하는 것은 실용적으로 충분히 안전할 수는 있지만, 완벽하게 안전할 수는 없다.

1. "완벽한 안전"이라는 질문의 함정

"완벽하게 안전한가?"라는 질문은 사실상 기밀성·가용성·사용성의 트릴레마를 간과한 질문이다. 어떤 시스템도 이 세 가지를 동시에 보장할 수 없다.

  • 기밀성(Confidentiality) — 키가 절대 유출되지 않음
  • 가용성(Availability) — 사용자가 필요할 때 항상 키에 접근 가능
  • 사용성(Usability) — 평범한 사용자가 실수 없이 다룰 수 있음

이 세 가지는 서로 맞물려 있어, 하나를 높이면 다른 쪽이 흔들린다. 키를 종이에 적어 금고에 넣고 인터넷과 완전히 단절하면 기밀성은 올라가지만 가용성과 사용성은 무너진다. 휴대폰은 정반대 지점, 즉 가용성·사용성을 높이는 대신 공격 표면을 넓힌 선택이다.

📱 휴대폰가용성·사용성 ↑ · 기밀성 ↓기밀성키가 절대 유출되지 않음가용성필요할 때 항상 접근사용성실수 없이 다룸
Fig 1. 보안 트릴레마 — 기밀성·가용성·사용성은 서로 맞물려 있어 셋을 동시에 최대화할 수 없다. 휴대폰은 가용성·사용성을 택하는 대신 공격 표면(기밀성 리스크)을 넓힌 지점에 있다.

따라서 물어야 할 것 — "완벽하게 안전한가?"가 아니라 "어떤 위협 모델을 전제로, 어느 정도까지 안전한가?" 이다.

2. 위협 모델 (Threat Model)

키 보관의 안전성은 "누구로부터, 무엇을 지키려 하는가"를 정의하지 않으면 평가할 수 없다.

공격자 유형역량휴대폰 키 보관의 방어 수준
일반 절도범 (기기 분실/도난)물리적 접근, 비밀번호 모름🟢 강함 — Secure Enclave + 생체인증으로 사실상 차단
원격 멀웨어 / 악성 앱앱 권한 내 코드 실행🟡 중간 — 샌드박스·키스토어로 키 추출은 어렵지만 화면·입력 가로채기 위험
피싱 / 소셜 엔지니어링사용자를 속여 서명·시드 입력 유도🔴 약함 — 하드웨어가 아무리 강해도 사용자가 직접 승인하면 무력
정교한 표적 공격 (0-day)커널/OS 취약점, 무클릭 익스플로잇🔴 약함 — Pegasus류 공격 앞에서는 격리 경계 붕괴 가능
국가급 / 공급망 공격펌웨어·하드웨어·인증서 체인 침투🔴 매우 약함 — 신뢰 기반 자체가 침해됨

핵심 통찰 — 휴대폰 키 보관은 일상적 위협(절도·분실)에는 매우 강하지만, 사용자를 속이는 공격(피싱)과 국가급 표적 공격에는 본질적으로 취약하다. 실제 자산 탈취의 상당수도 0-day가 아니라 피싱과 사용자 실수에서 발생한다.

3. 휴대폰은 키를 어떻게 보관하는가

현대 스마트폰은 키를 디스크에 평문으로 저장하지 않는다. 그러나 "어떻게 보관하는가"를 제대로 답하려면 한 문장으로는 부족하다. 키 보관을 세 가지 질문으로 분해해서 보자.

  1. 키는 어디에 사는가 — 저장 계층
  2. 무엇이 키 사용을 통제하는가 — 보호 메커니즘
  3. 보안 영역은 무엇을 보장하고, 무엇을 보장하지 못하는가 — 신뢰 경계와 그 한계

3.1 키는 어디에 사는가 — 저장 계층의 스펙트럼

같은 Keystore API를 호출해도, 실제 키가 어느 계층에 backing되는지에 따라 안전성은 완전히 달라진다. 키 저장 위치는 단일 지점이 아니라 보호 강도의 스펙트럼이다.

  • 소프트웨어 키스토어 — 키가 OS가 접근 가능한 영역에 (보통 암호화되어) 저장된다. 사용 시점에는 normal-world 메모리로 복호화되므로, OS가 뚫리면 키도 함께 위험해진다. 가장 약한 계층이다.
  • TEE(Trusted Execution Environment) — ARM TrustZone의 secure world에서 키 연산이 일어난다. normal-world의 안드로이드 커널과 격리되어 있어, 단순 루팅만으로는 키를 추출할 수 없다. 다만 TEE 자체의 취약점은 별도로 존재한다.
  • 전용 보안 칩(Secure Element) — iOS의 Secure Enclave, 안드로이드의 StrongBox(예: Pixel의 Titan M2)처럼 물리적으로 분리된 칩이다. 자체 CPU·메모리·난수원·내결함성을 갖춰 키 추출 난이도가 가장 높다. 단, StrongBox는 기기에 따라 없을 수 있다.
저장 계층격리 경계OS 루팅 시 키 추출예시
소프트웨어프로세스 · 디스크 암호화🔴 가능 — 메모리에서 복호화돼 노출구형·저가 기기 fallback
TEETrustZone secure world🟡 어려움 — TEE 취약점이 필요대부분의 안드로이드
전용 보안 칩물리적으로 분리된 SE🟢 사실상 불가SEP(iOS), StrongBox / Titan M2

같은 "휴대폰에 키를 둔다"도 이 표의 어느 행에 해당하느냐에 따라 위협 모델이 달라진다. 지갑이 어떤 계층을 요구하는지(예: 안드로이드의 setIsStrongBoxBacked(true))가 실제 보안 수준을 좌우한다.

3.2 무엇이 키 사용을 통제하는가 — 네 가지 보호 메커니즘

키를 "꺼낼 수 없게" 만드는 것(격리)은 네 가지 메커니즘 중 하나일 뿐이다. 현대 보안 칩은 다음을 함께 강제한다.

  1. 격리(Isolation) — 개인키 비트가 보안 경계 밖 메모리에 절대 나타나지 않는다. 앱이 다루는 것은 키가 아니라 키 핸들이다.
  2. 접근 게이팅(Auth binding) — 키 사용을 생체·패스코드 인증과 묶는다. iOS는 kSecAccessControl, 안드로이드는 setUserAuthenticationRequired. 인증 유효 범위는 시간 기반(한 번 인증 후 N초 동안 허용)과 건별(서명 한 번마다 재인증)으로 나뉜다.
  3. 레이트 리밋과 소거(Rate limiting / wipe) — 무차별 대입을 하드웨어 카운터로 지연시키고, 임계치를 넘으면 데이터를 소거한다. iOS는 패스코드 시도 간 지수적 지연과 자동 소거 옵션, 안드로이드는 Gatekeeper·Weaver throttling과 StrongBox의 모노토닉 카운터를 쓴다.
  4. 어테스테이션(Attestation) — 키가 실제로 하드웨어에 backing됐음을 인증서 체인으로 증명한다. 안드로이드 Key Attestation, iOS App Attest가 여기 해당한다. 서버가 "이 키는 진짜 보안 칩 안에 있다"를 원격으로 검증할 수 있다.

이 네 가지의 공통 뿌리는 하드웨어 신뢰의 근원(root of trust)이다. 칩에 영구 기록된 device UID와 부트 체인 검증이 깨지지 않았다는 가정 위에서만 위 보장이 성립한다.

3.3 iOS vs Android — 구현 비교

구분iOSAndroid
보안 하드웨어Secure Enclave (SEP)TEE (TrustZone) / StrongBox (전용 보안 칩)
키 저장 APIKeychain + Secure EnclaveAndroid Keystore
저장 계층 결정항상 SEP 또는 Data Protection 클래스 키로 보호소프트웨어 / TEE / StrongBox 중 기기·요청에 따라 결정
접근 통제Data Protection 클래스 + kSecAccessControlsetUserAuthenticationRequired + BiometricPrompt
키 추출 가능성비대칭 키는 SEP 밖으로 추출 불가 (서명만 위임)StrongBox·TEE 키는 추출 불가, 소프트웨어 키스토어는 상대적으로 약함
무차별 대입 방어패스코드 지연 + 자동 소거 옵션Gatekeeper·Weaver throttling, StrongBox 카운터
하드웨어 증명App Attest / DeviceCheckKey Attestation (구글 루트 체인)
생체 연동Face ID / Touch ID로 접근 게이팅BiometricPrompt + setUserAuthenticationRequired

3.4 신뢰 경계 (Trust Boundary) 구조

일반 영역
사용자 / 생체인증
지갑 앱
앱 장악 시도
멀웨어 / OS 취약점
네트워크 / 블록체인
서명 요청
서명 결과만 반환 (키 아님)
🔒 신뢰 경계 (Trust Boundary)
보안 영역
Secure Enclave / StrongBox
개인키(raw bits)는 이 경계 안에서만 존재 — 밖으로 나가지 않는다

멀웨어가 앱을 완전히 장악해도 키는 못 꺼낸다. 단, 원하는 트랜잭션에 서명을 '요청'할 수는 있다 (Fig 4).

Fig 2. 신뢰 경계 구조 — 개인키는 보안 영역(SEP/StrongBox) 안에서만 존재하고, 앱은 서명을 '요청'만 한다. 멀웨어가 앱을 장악해도 키 자체는 경계를 넘지 못한다.

핵심은 개인키가 보안 영역 밖으로 나오지 않고, 서명 연산만 맡긴다는 점이다. 이상적으로 동작하면 멀웨어가 앱을 완전히 장악해도 키 자체는 빼낼 수 없다. 그러나 이 모델에는 두 가지 근본적 한계가 있다.

  1. 서명 위임의 역설 — 키를 빼내지 못해도, 멀웨어가 원하는 트랜잭션에 서명을 요청하면 보안 영역은 그대로 서명해준다. 키의 기밀성은 지켜지지만 자산은 털릴 수 있다.
  2. 신뢰 경계의 전제 — "보안 영역은 안전하다"는 가정은 펌웨어·OS·하드웨어가 침해되지 않았을 때만 성립한다.

3.5 Secure Enclave의 두 가지 결정적 제약 — Export 불가, 그리고 알고리즘 불일치

블록체인 지갑 관점에서 Secure Enclave(SEP)에는 흔히 간과되는 두 가지 제약이 있다.

① 개인키를 export할 수 없다 (Non-exportable by design)

SEP에서 생성된 키는 칩 내부에서 만들어지며, 개인키 비트는 SEP 경계를 절대 벗어나지 않는다. 앱이 다루는 것은 키 자체가 아니라 키를 가리키는 불투명한 참조값(iOS의 SecKey, Android의 KeyStore alias)뿐이다.

  • 앱은 "이 데이터에 서명해줘" / "이 값과 ECDH 해줘"라고 요청만 할 수 있고, 키 원본(raw bytes)은 읽을 수 없다.
  • 루팅·탈옥으로 OS를 장악해도 SEP 밖으로 키를 꺼낼 수 없다 (얻는 것은 여전히 핸들뿐).
  • 장점: 멀웨어가 키를 복사해 다른 기기로 가져갈 수 없다.
  • 단점(역설): 백업·다른 기기로의 이전·시드 문구 표시가 원천적으로 불가능하다. 그래서 SEP 키는 "분실하면 끝"이며, 가용성 측면에서는 오히려 부담이 된다.

② 지원 알고리즘이 달라 블록체인 키로 직접 쓸 수 없다

여기가 핵심이다. Secure Enclave가 하드웨어 수준에서 지원하는 것은 NIST P-256(secp256r1, prime256v1) 곡선의 ECC 키와 ECDSA/ECDH 연산뿐이다.

구분곡선 / 알고리즘SEP에서 직접 서명 가능?
Bitcoin / Ethereum (EOA)secp256k1 (ECDSA)❌ 불가 — SEP가 지원하지 않는 곡선
Solana / Aptos 등Ed25519❌ 불가 — SEP 미지원
Secure Enclave 네이티브secp256r1 (P-256)✅ 가능 — 단, 체인이 P-256 검증을 지원해야 의미 있음

이더리움 개인키를 SEP 안에 넣고 secp256k1 서명을 만들어내는 것은 불가능하다. secp256k1과 secp256r1은 곡선 파라미터가 다른 별개의 암호 체계이기 때문이다. 그래서 현실의 모바일 지갑은 두 가지 우회 패턴 중 하나를 쓴다.

  1. SEP 키를 래핑 키(KEK)로 사용 — 실제 secp256k1 개인키는 Keychain/Keystore에 암호화된 상태로 저장하고, 그 암호화 키를 SEP가 생체인증으로 게이팅한다. 서명 시점에 키를 앱 메모리로 복호화해야 하므로 짧은 노출 구간이 남는다.
  2. P-256 키를 AA 계정의 서명자로 사용 — Ethereum EOA 자체를 secp256r1로 바꾸는 것이 아니라, AA(Account Abstraction) 계정이 P-256 서명을 유효한 소유자 서명으로 인정하게 만든다. ERC-4337은 실행 모델을, ERC-1271은 컨트랙트 서명 검증 인터페이스를, ERC-7913은 Ethereum 주소가 없는 키를 서명자로 표현하는 방식을 제공하고, RIP-7212/EIP-7951 계열 precompile은 P-256 검증 비용을 낮춘다.
SEP 내부 P-256 키
export 불가 — 키 비트는 SEP 밖으로 안 나감
블록체인 서명 요구
secp256k1 · Ed25519
곡선 불일치로 직접 서명 불가
패턴 1 · 래핑 키(KEK)
실제 secp256k1 키를 암호화해 저장하고, 그 암호화 키를 SEP가 생체인증으로 게이팅한다.
서명 시 앱 메모리로 복호화 → 짧은 노출 구간 발생
패턴 2 · AA 계정의 P-256 서명자
ERC-4337 · ERC-1271 · ERC-7913이 P-256 서명을 유효한 소유자 서명으로 인정한다.
시드 문구 불필요 → Passkey가 직접 소유자 키 역할
Fig 3. Secure Enclave의 곡선 불일치 — SEP는 밖으로 꺼낼 수 없는 P-256 키만 다루지만, 블록체인은 secp256k1·Ed25519 서명을 요구한다. 그래서 실제 모바일 지갑은 두 우회 패턴 중 하나를 쓴다.

정리하면 — SEP는 "키를 빼낼 수 없는 금고"지만, 그 금고가 다룰 수 있는 열쇠 모양(P-256)이 블록체인이 요구하는 열쇠 모양(secp256k1)과 다르다. 이 불일치가 모바일 지갑 설계의 핵심 제약이자, Passkey 기반 AA로 전환하게 만드는 동력이다.

4. 공격 경로별 분석

4.1 물리적 탈취 — 방어 우수 🟢

기기를 훔쳐도 잠금 화면·생체인증·SEP 결합으로 키 접근이 차단된다. 무차별 대입은 하드웨어 레벨에서 시도 횟수가 제한되고 데이터가 소거된다. 이 영역에서 휴대폰은 종이지갑보다 안전할 수 있다.

4.2 멀웨어 / 악성 앱 — 부분 방어 🟡

  • 앱 샌드박스와 키스토어 덕분에 키 추출은 어렵다.
  • 그러나 오버레이 공격(가짜 화면), 접근성 권한 남용, 클립보드 하이재킹(주소 바꿔치기), 스크린 캡처로 시드 문구를 노릴 수 있다.
  • 특히 시드 문구를 사용자가 화면에 입력·표시하는 순간이 가장 약한 고리다.

아래는 앞에서 말한 서명 위임의 역설—키는 안전하지만 자산은 털리는 공격 흐름이다.

멀웨어악성 dApp지갑 앱사용자Secure Enclave/ StrongBox블록체인🔑키 고정악성 트랜잭션 서명 요청승인 요청 (위장된 화면)승인 (속아서)서명 위임서명 반환악성 트랜잭션 전파키는 유출되지 않았지만자산은 탈취됨
Fig 4. 서명 위임의 역설 — 멀웨어는 키를 빼내지 못해도, 사용자를 속여 서명을 '요청'하게 만들면 보안 영역은 그대로 서명해준다. 키의 기밀성은 지켜지지만 자산은 털린다.

4.3 사이드채널 / 추론 공격 — 잔존 위험 🟡

전력 분석, 타이밍, 캐시 공격 등은 학술적으로 입증되어 있다. 일반 사용자에게는 비현실적이지만 고가치 표적에는 유효할 수 있다.

4.4 OS / 커널 0-day — 막아내기 어려운 영역 🔴

Pegasus나 무클릭 iMessage 익스플로잇 사례처럼, 커널 권한을 탈취한 공격자는 신뢰 경계 자체를 우회하거나 서명 흐름을 조작할 수 있다. 이 단계에 이르면 "하드웨어가 키를 지킨다"는 보장은 크게 약해진다.

4.5 피싱 / 소셜 엔지니어링 — 최대 위협 🔴

기술적으로 가장 견고한 지갑도, 사용자가 악성 트랜잭션에 직접 서명하거나 시드를 가짜 사이트에 입력하면 무력해진다. 실제 손실의 대부분이 여기서 발생한다. 이는 휴대폰만의 문제가 아니라, 신뢰 여부를 마지막에 판단하는 주체가 결국 사람이라는 구조적 한계다.

5. 왜 "완벽"이 불가능한가 — 구조적 이유

구조의 문제 — 완벽한 안전을 가로막는 것은 특정 버그 하나가 아니라 시스템 구조 자체다.

  • 겹겹이 쌓인 신뢰 전제 — 칩 제조사 → 펌웨어 → OS → 앱 → 사용자까지 여러 단계가 모두 안전하다고 가정해야 한다. 이 중 어느 한 단계만 깨져도 전체 보장은 무너진다. 사용자는 이 전제들을 직접 검증할 수 없다.
  • 검증하기 어려운 TCB(Trusted Computing Base) — Secure Enclave 펌웨어는 폐쇄적이며 사용자가 직접 감사할 수 없다. 결국 "안전하다고 믿는" 영역이지, 사용자가 스스로 증명할 수 있는 영역은 아니다.
  • 마지막 판단자인 사람 — 최종 승인은 사람이 한다. 사회공학은 암호학을 정면으로 깨지 않고도 우회한다.
  • 방어와 공격의 비대칭성 — 방어자는 모든 구멍을 막아야 하지만, 공격자는 하나만 찾으면 된다.
  • 시간차 문제(TOCTOU 류) — 검증한 시점과 실제로 사용하는 시점 사이에 상태가 바뀔 수 있다. 안전은 한순간의 스냅샷이 아니라 계속 흔들리고 침식되는 상태다.
완벽한 안전 주장
= 아래 모든 단계가 안전하다는 가정
공격자
어느 한 단계만 깨도 충분
칩 제조사하드웨어 설계
펌웨어Secure Enclave / TEE
OS커널 · 권한 모델
지갑 앱구현 · UX
사용자승인 · 판단
피싱 · 사회공학
자산 이동 승인

방어와 공격의 비대칭 — 방어자는 모든 구멍을 막아야 하지만, 공격자는 단 하나만 찾으면 된다.

Fig 5. 겹겹이 쌓인 신뢰 전제 — '완벽한 안전'은 칩 제조사부터 사용자까지 모든 단계가 안전하다는 가정 위에 있다. 방어자는 모든 단계를 지켜야 하지만, 공격자는 하나만 뚫으면 된다.

6. 그렇다면 어떻게 "충분히" 안전하게 만드는가

완벽이 불가능하다고 해서 "포기하라"는 뜻은 아니다. 핵심은 단일 실패점(single point of failure)을 없애고 위험을 분산하는 것이다.

완화 전략막아내는 위협트레이드오프
하드웨어 키스토어 강제 (StrongBox/SEP)키 추출, 물리적 탈취구형 기기 호환성
생체 + 트랜잭션 단위 인증무단 서명, 백그라운드 멀웨어사용성 마찰 증가
MPC (다자간 연산) / 키 분할단일 기기 침해구현 복잡도, 인프라 의존
멀티시그 (다중 서명)단일 키 탈취, 내부자UX 복잡, 가스 비용
소셜 리커버리 / AA 계정키 분실, 가용성 문제가디언 신뢰·담합 위험
거래 한도 · 화이트리스트 · 타임락피싱 후 즉시 탈취긴급 송금 불편
하드웨어 지갑 분리 (콜드 키)온라인 공격 전반휴대성·편의성 희생

여러 방어막을 겹겹이 쌓아 한 계층이 뚫려도 다음 계층이 막아주게 만드는 계층 방어(defense in depth) 구조는 다음과 같다.

위협멀웨어 · 피싱 · 분실 · 0-day
1하드웨어 키스토어
2트랜잭션 단위 생체 인증
3키 분산
4정책
5자산 분리
🎯 보호 대상 자산
Fig 6. 계층 방어(defense in depth) — 한 계층이 뚫려도 다음 계층이 막는다. 하드웨어 키스토어부터 자산 분리까지 다섯 겹이 자산을 감싼다.

실무 권고 — 휴대폰에 키를 두는 것은 소액·일상 거래에 합리적인 선택이다. 단, ① 하드웨어 키스토어를 강제하고 ② 트랜잭션마다 명시적으로 생체 승인을 받으며 ③ 고액 자산은 멀티시그/MPC 또는 콜드 월렛으로 분리하고 ④ 한도·화이트리스트로 피싱 피해를 제한하는 계층 방어(defense in depth)가 필요하다. "키를 어디 두느냐"보다 "위험을 어떻게 분산하느냐"가 더 중요하다.

자산 규모에 따른 보관 전략 선택은 대략 다음 기준을 따른다.

보관할 자산 규모는?
소액 · 일상 거래
휴대폰 핫월렛
SEP + 트랜잭션 생체 승인
온라인 노출 ↑
중간 규모
AA 계정
MPC / 소셜 리커버리 + 한도
위험 분산
고액 · 장기 보관
콜드 월렛 / 멀티시그
오프라인 분리
온라인 노출 ↓
Fig 7. 자산 규모에 따른 보관 전략 — 소액은 휴대폰 핫월렛, 중간 규모는 AA 계정, 고액·장기 보관은 콜드 월렛/멀티시그. 자산이 클수록 온라인 노출을 줄이는 쪽으로 옮긴다.

7. Passkey로 키 관리를 대체하는 기법

앞서 본 SEP의 제약(내보내기 불가 + P-256만 지원)은 역설적으로 Passkey와 정확히 맞물린다. Passkey는 본질적으로 SEP/StrongBox에 저장되는, 밖으로 꺼낼 수 없는 P-256(secp256r1) 키쌍이기 때문이다. 시드 문구 기반 키 관리를 Passkey로 대체하려는 흐름은 다음과 같이 정리된다.

7.1 Passkey란

  • WebAuthn/FIDO2 표준의 자격증명으로, 하드웨어 보안 영역에 저장된 P-256 키쌍이다. 개인키는 SEP 밖으로 나오지 않는다.
  • 출처 바인딩(origin-bound)이라 가짜 사이트에서는 서명 요청 자체가 성립하지 않는다 → 구조적으로 피싱에 강하다. (시드 문구의 가장 큰 약점을 정면으로 보완)
  • iCloud Keychain / Google Password Manager로 동기화(synced passkey)되거나, 특정 기기에 묶이는 device-bound passkey로 운용된다.

7.2 Passkey 기반 지갑을 구성하는 표준 조합

Passkey가 "지갑 키를 대체한다"는 말은 Ethereum EOA가 곧바로 secp256r1 트랜잭션을 서명한다는 뜻이 아니다. 더 정확히는 Passkey의 P-256 키를 AA(Account Abstraction) 계정의 소유자 키로 인정하고, 그 서명을 표준화된 검증 경로로 처리한다는 뜻이다.

구성 요소담당하는 층핵심 역할
Passkey / WebAuthn사용자 기기SEP/StrongBox 안의 P-256 키가 사용자 생체 인증 후 서명한다. 개인키는 기기 밖으로 나오지 않는다.
ERC-4337AA 실행 모델EOA 서명 없이 UserOperation을 제출하고, AA 계정의 validateUserOp가 소유자 서명을 검증한다.
ERC-1271컨트랙트 서명 호환성AA 계정이 isValidSignature(hash, signature)로 "이 서명은 이 계정에 대해 유효하다"고 표준 방식으로 응답한다.
ERC-7913주소 없는 서명자 표현P-256처럼 Ethereum 주소가 없는 키를 verifier || key 형태의 signer로 표현하고, 전용 verifier가 검증한다.
RIP-7212 / EIP-7951EVM precompilesecp256r1 서명 검증을 EVM에서 싸고 빠르게 처리해 Passkey 기반 AA를 실용화한다.

이 조합에서 각 표준의 역할은 서로 겹치지 않는다. ERC-4337은 "어떻게 AA 계정이 트랜잭션을 실행할 것인가"를 다루고, ERC-1271은 "컨트랙트 계정의 서명을 외부에서 어떻게 검증할 것인가"를 다루며, ERC-7913은 "Ethereum 주소가 없는 키를 signer로 어떻게 표현할 것인가"를 다룬다. RIP-7212/EIP-7951은 이 모든 구조가 가스 비용 때문에 비현실적으로 변하지 않도록 P-256 검증을 네이티브 연산에 가깝게 낮춰주는 기반이다.

사용자
Passkey / WebAuthn
P-256 서명 생성
UserOperation
서명 데이터 포함
ERC-4337 AA 계정
validateUserOp
ERC-1271
외부 서명 검증 인터페이스
ERC-7913
주소 없는 signer 표현
P-256 verifier
RIP-7212 / EIP-7951
P-256 precompile
검증 성공?
트랜잭션 실행
아니오
거부
Fig 8. Passkey 기반 AA 지갑의 표준 조합 — Passkey가 만든 P-256 서명을 ERC-4337 AA 계정이 받고, ERC-1271·ERC-7913로 해석한 뒤 P-256 precompile로 검증한다. EOA가 아니라 AA 계정의 소유자 키로 동작한다.

7.3 ERC-1271 — AA 계정의 서명을 외부 세계와 호환시키는 표준

EOA는 주소와 개인키가 1:1로 묶여 있고, 서명 검증도 ecrecover 중심으로 동작한다. 반면 AA 계정은 컨트랙트이므로 "이 계정이 어떤 서명을 유효하다고 볼 것인가"를 내부 로직으로 정할 수 있다. 이때 외부 dApp, 프로토콜, 컨트랙트가 매번 각 지갑의 내부 구현을 알 필요는 없다. ERC-1271은 컨트랙트 계정이 서명 유효성을 표준 인터페이스로 답하게 해주는 규격이다.

  • 핵심 함수는 isValidSignature(hash, signature)다.
  • AA 계정은 내부에서 P-256, secp256k1, 멀티시그, 세션 키, 소셜 리커버리 등 어떤 검증 방식을 쓰든 상관없이, 최종적으로 "유효함" 또는 "유효하지 않음"을 표준 형식으로 반환한다.
  • Passkey 지갑에서는 signature 안에 WebAuthn 서명 데이터와 필요한 메타데이터가 들어가고, AA 계정은 이를 해석해 P-256 검증 경로로 넘긴다.
  • 즉 ERC-1271은 P-256을 직접 정의하는 표준이 아니라, P-256 기반 AA 계정이 기존 dApp 생태계와 호환되도록 해주는 접점이다.

한 문장 요약 — ERC-1271은 "컨트랙트 지갑도 표준 방식으로 서명 검증 결과를 말할 수 있게 해주는 규격"이다. Passkey는 이 내부 검증 로직의 한 종류로 들어간다.

7.4 ERC-7913 — Ethereum 주소가 없는 키를 signer로 다루는 방식

P-256 Passkey의 어려움은 단지 검증 비용만이 아니다. secp256k1 EOA처럼 자연스럽게 Ethereum 주소가 생기는 키가 아니기 때문에, "이 P-256 공개키를 어떤 signer로 표현할 것인가"라는 문제가 생긴다. ERC-7913은 이 지점을 다룬다.

  • 기존 모델에서는 signer가 대체로 Ethereum address다.
  • 하지만 Passkey, 하드웨어 보안 키, RSA 키, 다른 체계의 공개키는 그 자체로 Ethereum 주소를 갖지 않는다.
  • ERC-7913은 signer를 단순 주소가 아니라 verifier || key 형태의 바이트열로 표현한다.
  • 여기서 verifier는 해당 키 타입을 검증할 컨트랙트 주소이고, key는 P-256 공개키 등 실제 식별자다.
  • 검증 시에는 signer에 포함된 verifier가 signature를 해석하고, 필요한 경우 P-256 precompile을 호출해 서명을 검증한다.

이 방식의 장점은 AA 계정이 여러 종류의 키를 같은 틀 안에서 다룰 수 있다는 점이다. 예를 들어 한 계정이 다음과 같은 signer 조합을 가질 수 있다.

  • iPhone Passkey P-256 키
  • Android StrongBox P-256 키
  • 하드웨어 보안 키
  • 복구용 guardian 키
  • 세션 키 또는 제한 권한 키

즉 ERC-7913은 Passkey를 "특수 예외"로 처리하기보다, 주소 없는 키 전반을 AA 계정의 signer로 편입시키는 일반화된 표현 방식에 가깝다.

signer (bytes)
verifier
20 bytes — 검증 컨트랙트 주소
key
P-256 공개키 등 실제 식별자
signature · WebAuthn / P-256 서명
verifier가 signature를 해석 → 필요 시 P-256 precompile 호출
유효한 signer인가?
AA 계정 owner로 인정
아니오
검증 실패
Fig 9. ERC-7913의 주소 없는 signer 표현 — Ethereum 주소가 없는 P-256 키를 'verifier ‖ key' 바이트열로 표현한다. verifier가 signature를 해석하고, 필요하면 P-256 precompile을 호출해 검증한다.

7.5 RIP-7212와 EIP-7951 — P-256 검증을 실사용 가능한 비용으로 낮추는 기반

P-256 서명은 원래 WebAuthn·Passkey·Secure Enclave·Android Keystore가 널리 쓰는 곡선이다. 문제는 EVM이 전통적으로 secp256k1 중심으로 설계되어 있었고, P-256 검증을 Solidity만으로 구현하면 가스 비용이 너무 크다는 점이다.

  • RIP-7212는 주로 L2/rollup 환경에서 secp256r1 검증 precompile을 제공하려는 제안이다. Passkey 기반 지갑이 L2에서 빠르게 실험되고 실용화될 수 있었던 이유가 여기에 있다.
  • EIP-7951은 Ethereum 본류의 EIP 흐름에서 secp256r1 검증 precompile을 표준화하려는 방향이다. RIP-7212 계열 구현과의 호환성을 고려하면서, P-256 검증을 더 안전하고 명확한 체인 레벨 기능으로 다루려는 성격이 강하다.
  • precompile이 있으면 AA 계정이나 verifier 컨트랙트는 복잡한 타원곡선 연산을 Solidity로 직접 수행하지 않고, 정해진 precompile에 hash, r, s, 공개키 좌표 등을 넘겨 검증 결과를 받을 수 있다.
  • 결과적으로 P-256 검증은 "가능은 하지만 비싼 기능"에서 Passkey 지갑에 실제로 쓸 수 있는 기능으로 바뀐다.

precompile의 핵심 — RIP-7212/EIP-7951의 핵심은 "Passkey가 서명하게 해준다"가 아니라, Passkey가 만든 P-256 서명을 온체인에서 감당 가능한 비용으로 검증하게 해준다는 점이다. 서명은 기기 안의 SEP/StrongBox가 만들고, 체인은 그 서명이 유효한지만 확인한다.

Solidity만으로 P-256 검증
복잡한 타원곡선 연산을 직접 수행
큰 가스 비용
실사용 지갑 UX에 부담
P-256 precompile 사용
고정된 네이티브 검증 경로
낮은 가스 비용 · 단순한 verifier
Passkey 기반 AA 실용화
Fig 10. P-256 검증 비용 — Solidity만으로 구현하면 가스가 비싸 지갑 UX에 부담이 되지만, precompile을 쓰면 네이티브 검증으로 비용이 낮아져 Passkey 기반 AA가 실용화된다.

7.6 secp256r1을 직접 서명자로 쓴다는 말의 정확한 의미

곡선 불일치 문제는 "EOA 서명 알고리즘을 바꾼다"기보다 서명 검증의 위치를 AA 계정으로 옮긴다는 방식으로 해결된다.

  • EOA는 여전히 secp256k1 중심 — 기본 Ethereum 계정의 트랜잭션 서명 체계는 secp256r1로 바뀐 것이 아니다.
  • AA 계정은 서명 규칙을 스스로 정의 — ERC-4337 계정은 validateUserOp 안에서 P-256, 멀티시그, 소셜 리커버리 등 원하는 소유자 규칙을 구현할 수 있다.
  • ERC-1271은 외부 호환성을 제공 — dApp이나 다른 컨트랙트는 AA 계정의 내부 키 종류를 몰라도 표준 인터페이스로 서명 유효성을 확인할 수 있다.
  • ERC-7913은 P-256 키를 signer로 표현 — Passkey처럼 Ethereum 주소가 없는 키도 독립적인 signer로 다룰 수 있게 해준다.
  • RIP-7212/EIP-7951은 비용 문제를 해결 — P-256 검증을 Solidity로만 처리하면 비싸지만, precompile이 있으면 실사용 가능한 수준으로 낮아진다.

전체 흐름은 다음과 같다. 시드 문구나 secp256k1 EOA 키가 아니라, SEP 안의 Passkey가 AA 계정의 소유자 서명자로 동작한다.

사용자PasskeySEP · P-256번들러AA 계정ERC-4337서명 검증ERC-7913 · 1271P-256 검증RIP-7212 / 7951🔑키 고정생체 인증으로 서명 승인P-256 서명 생성 (키는 SEP 밖으로 안 나감)서명된 UserOperation 전송UserOperation 제출signer와 signature 해석secp256r1 서명 검증검증 성공유효한 소유자 서명으로 판정트랜잭션 실행EOA가 아니라 AA 계정의 owner key로 직접 사용
Fig 11. Passkey가 AA 계정의 소유자 서명자로 동작하는 전체 흐름 — 시드 문구나 secp256k1 EOA 키가 아니라, SEP 안의 Passkey가 P-256 서명을 만들고 체인은 그 서명의 유효성만 검증한다.

7.7 트레이드오프 — Passkey가 만능은 아니다

반드시 인지할 것 — Passkey는 피싱 저항성·내보내기 불가·UX 개선이라는 큰 장점이 있지만, 키 보관의 신뢰 기반을 클라우드 계정 쪽으로 옮긴다는 점을 반드시 인지해야 한다.

  • 동기화 Passkey의 커스터디 이전 — iCloud/Google 계정이 탈취되면 동기화된 Passkey도 위험하다. 즉 지갑 보안이 클라우드 계정 보안에 종속된다. (device-bound로 두면 안전하지만 분실 시 복구 불가)
  • 곡선/가스 비용 — precompile이 없는 체인에서는 P-256 온체인 검증이 비싸다.
  • AA 인프라 의존 — Passkey가 직접 서명자로 쓰이는 경로는 EOA가 아니라 AA 계정을 전제한다. 따라서 ERC-4337 번들러, Paymaster, verifier 컨트랙트, 그리고 체인의 P-256 precompile 지원 여부에 영향을 받는다.
  • "키 제거"가 아니라 "키 위임" — Passkey도 결국 키다. 단일 Passkey에만 의존하면 단일 실패점이 되므로, 다중 Passkey·멀티시그·소셜 리커버리와 결합해야 한다.

요약 — Passkey 기반 설계는 "시드 문구를 사람이 보관·입력"하는 모델의 약점(피싱·분실·노출)을 구조적으로 줄인다. 특히 Passkey(P-256) → ERC-7913/1271 서명 검증 → ERC-4337 AA 계정 → RIP-7212/EIP-7951 precompile 조합은 SEP의 알고리즘 제약을 우회하면서 export 불가 보안을 그대로 살리는, 현재 가장 유망한 방향이다. 다만 이는 EOA 자체의 서명 체계를 바꾸는 것이 아니라 AA 계정의 소유자 검증 방식을 바꾸는 것이며, 신뢰 가정이 클라우드 계정으로 이동한다는 점도 위협 모델에 반드시 반영해야 한다.

8. 결론

휴대폰에 지갑 키를 보관하는 것은 완벽하게 안전할 수 없다. 그러나 그것은 휴대폰의 결함이라기보다, 어떤 키 보관 방식도 완벽할 수 없다는 보안의 근본 명제에서 비롯된다.

  • 완벽한 안전은 존재하지 않는다. 겹겹의 신뢰 전제, 검증하기 어려운 TCB, 마지막 판단자인 사람이라는 구조적 한계 때문이다.
  • 휴대폰은 일상 위협(분실·도난)에 강하고, 표적 공격·피싱에 약하다. 위협 모델에 따라 평가가 완전히 달라진다.
  • 실제 손실의 대부분은 암호학의 붕괴가 아니라 사용자 기만에서 온다. 따라서 UX와 권한 설계가 암호 알고리즘만큼 중요하다.
  • Secure Enclave는 키를 export할 수 없게 만들지만, secp256k1을 직접 지원하지 않는다. 그래서 SEP는 보통 래핑 키로 쓰이거나, Passkey(P-256)를 ERC-4337 AA 계정의 소유자 키로 쓰고 ERC-1271/7913 및 RIP-7212/EIP-7951 계열 검증 경로로 처리하는 흐름이 부상하고 있다.
  • 올바른 목표는 "완벽"이 아니라 "단일 실패점 제거 + 위험 분산 + 피해 한정"이다.

결국 보안은 상태(state)가 아니라 과정(process)이다. "완벽하게 안전한가?"라는 이분법적 질문을 "내 위협 모델에 대해 수용 가능한 위험 수준인가?"라는 공학적 질문으로 바꾸는 것이, 이 주제에 대한 가장 정확한 답이다.

부록 — 직접 실험으로 확인하기

이 글의 핵심 주장들은 추상적 설명에 그치지 않는다. 로컬에서 직접 실험으로 확인했고, 전체 코드는 공개 저장소 passkey-lab에 있다.

  • Passkey = P-256 키 — 브라우저 WebAuthn으로 Passkey(ES256/P-256)를 만들고 서명한 뒤, 그 서명을 crypto.subtle.verify로 검증했다. 개인키는 보안 영역 밖으로 나오지 않고, 나오는 것은 공개키와 서명뿐이다.
  • Secure Enclave 서명 — Apple Silicon Mac에서 CryptoKit SecureEnclave.P256.Signing.PrivateKey()로 SEP 안에 키를 만들고 서명·검증했다 (Secure Enclave available: true, verified locally: true).
  • AA 계정의 P-256 소유자 (ERC-1271) — secp256k1 EOA 없이, P-256 공개키를 소유자로 갖는 컨트랙트가 isValidSignature에서 Passkey 서명에 ERC-1271 매직값 0x1626ba7e를 돌려준다.
  • 온체인 P-256 검증 비용 — 같은 서명을 온체인에서 검증할 때 순수 Solidity 구현은 약 255,423 가스로 측정됐고, RIP-7212/EIP-7951 precompile은 명세상 3,450 가스다. 이 약 74배 차이가 precompile이 Passkey 기반 AA를 실용화하는 이유를 그대로 보여준다.

특히 브라우저 데모가 출력하는 서명을 그대로 Foundry 테스트에 넣으면, 내 실제 Passkey 서명이 컨트랙트에 의해 온체인에서 검증된다.

ERC-1271 + P-256 검증의 핵심은 짧다.

// P256Account.sol — 소유자가 secp256k1 EOA가 아니라 P-256(Passkey) 키다.
function isValidSignature(bytes32 hash, bytes calldata signature)
    external view returns (bytes4)
{
    (bytes32 r, bytes32 s) = abi.decode(signature, (bytes32, bytes32));
    return P256.verify(hash, r, s, qx, qy) ? bytes4(0x1626ba7e) : bytes4(0xffffffff);
}

참고 자료

모바일 보안 하드웨어

Passkey · WebAuthn

계정 추상화 · 서명 검증 표준

실험 코드

  • passkey-lab — 이 글의 개념을 직접 확인한 실험 코드 (Passkey · Secure Enclave · 온체인 P-256).

댓글