시냅스

Road to Web3 (6) 지갑은 키 관리 + 서명기: 주소/개인키/공개키 본문

Road To Web3/Blockchain

Road to Web3 (6) 지갑은 키 관리 + 서명기: 주소/개인키/공개키

ted k 2025. 12. 28. 12:17
이 글은 Ethereum 및 EVM 계열을 기준으로 설명합니다. 저는 암호학을 기반으로 한 서비스를 개발해본 경험이 있어서, 이번 편은 조금 더 깊이 이해하고자 합니다. 다만 제품/운영 관점에서 바로 쓸 수 있는 감각 위주로 정리합니다.

 

 

제가 처음 지갑을 접했을 때 했던 오해는 이런 거였습니다.

  • 지갑 wallet 은 코인을 담는 통이다
  • 계정 account 은 사이트 로그인 계정 같은 것이다
  • 주소 address 는 사용자 ID 다

하지만 블록체인에서 지갑은 물리적 저장소가 아니라, 거의 전적으로 다음 두 가지입니다.

지갑 = 키 관리 + 서명기
계정 = 체인이 인식하는 상태를 가진 주체(주로 주소로 식별)

 

이 한 문장만 정확히 잡으면, 이후의 서명, 트랜잭션, 보안, 운영 모델이 한 번에 정리됩니다.


 

요약

개념 한 줄 정의 실무 포인트
개인키 private key 서명을 만드는 비밀 값 유출되면 끝. 회수 불가
공개키 public key 개인키로부터 도출되는 검증용 키 주소를 만드는 재료
주소 address 공개키에서 파생된 식별자 계정의 이름표(식별자)
서명 signature 키 소유 증명 + 의사 표명 메시지 서명과 tx 서명은 다르다
지갑 wallet 키를 안전하게 보관하고 서명하는 도구 실제 코인은 체인 상태에 있다

 

1) 계정은 로그인 계정이 아니다

Ethereum의 계정 2종류

Ethereum에서 account 라는 말은 보통 두 종류를 포함합니다.

  • EOA(Externally Owned Account): 개인키가 직접 통제하는 계정
  • 컨트랙트 계정(contract account): 코드가 통제하는 계정(스마트컨트랙트)

EOA는 키로 제어되고, 컨트랙트는 코드로 제어됩니다.
둘 다 주소를 가집니다. 하지만 서명 주체는 EOA만 됩니다.

컨트랙트는 서명을 하지 않는다. 컨트랙트는 규칙대로 실행될 뿐이다.


 

2) 개인키 → 공개키 → 주소

Ethereum EOA를 기준으로 흐름은 이렇습니다.

  1. 개인키: 32byte 정수 범위의 비밀값
  2. 공개키: secp256k1 타원곡선 곱셈으로 도출되는 점 (보통 64byte)
  3. 주소: 공개키에서 Keccak-256 해시를 취해 마지막 20바이트 (160-bit)

즉, 주소는 공개키의 해시 기반 축약 식별자에 가깝습니다.

 

주소는 공개키를 바로 담고 있지 않다

주소만 보고 공개키를 복원할 수는 없습니다.
다만 트랜잭션 서명에는 공개키 복원에 필요한 정보가 함께 들어가서, 네트워크는 서명 검증 과정에서 발신자 주소를 계산할 수 있습니다.

 

참고.
Ethereum의 keccak256은 Keccak 기반의 스펀지(sponge) 구조를 사용해, SHA-256(SHA-2)이 쓰는 압축함수 반복(Merkle–Damgard 계열)과 구조적으로 다릅니다. 그래서 keccak256은 SHA-256의 변형이 아니라 SHA3(Keccak) 계열에 더 가깝습니다. 다만 NIST 표준 SHA3-256은 패딩/도메인 분리가 달라, Ethereum의 keccak256과 결과가 같다고 보면 안 됩니다.

 

3) 서명은 무엇을 증명하나

서명은 본질적으로 다음을 증명합니다.

  • 이 메시지(또는 트랜잭션)의 내용을 승인한 사람이
  • 해당 개인키를 가진 주체다

즉, 서명은 암호학적으로는 인증(ownership proof)이고, 프로토콜적으로는 권한 위임(authorization)입니다.

Ethereum에서 서명은 보통 ECDSA(secp256k1) 기반입니다.

  • 메시지 m을 해시 h로 만든 뒤
  • 개인키로 (r, s, v) 형태의 서명을 생성
  • 검증자는 서명과 h를 이용해 공개키를 복원하고 검증

서명은 로그인이 아니라 권한 있는 API 호출

web2에서 로그인 세션이 인증이라면, 블록체인 서명은 요청마다 “내가 이 요청을 승인한다”를 암호학적으로 찍는 모델입니다.

  • 세션 쿠키가 없다
  • 대신 매 요청이 서명으로 권한을 증명한다

 

참고.
Ethereum 서명은 키 소유 기반 요청 승인이라는 점에서 DPoP와 철학이 비슷하지만, DPoP가 토큰 사용을 요청에 바인딩하는 메커니즘이라면 Ethereum은 원장 상태 변경을 트랜잭션(Nonce/ChainId 포함)에 바인딩해 네트워크 합의로 커밋한다는 점이 다르다.

 


 

4) 메시지 서명 vs 트랜잭션 서명: 헷갈리는 포인트

여기서부터 실무 사고가 갈립니다. Ethereum에서는 크게 두 가지 서명이 자주 등장합니다.

A) 메시지 서명 message signing

대표적으로 지갑의 signMessage 같은 기능입니다.

  • 목적: 로그인, 소유 증명, 오프체인 계약
  • 체인 상태를 바꾸지 않는다
  • 가스비가 없다(온체인 실행이 아니니까)

하지만 중요한 점이 하나 있습니다.

  • 메시지 서명은 온체인에서 자동으로 효력이 생기지 않습니다.
  • 누군가 그 서명을 검증하고, 그 결과로 무언가를 해줘야 합니다(보통 서버가).

B) 트랜잭션 서명 transaction signing

트랜잭션 서명은 체인 상태 변경 요청에 대한 서명입니다.

  • 목적: 전송, 컨트랙트 호출, 승인 approve 등
  • 네트워크에 브로드캐스트되고 블록에 포함되면 상태가 바뀐다
  • 가스비가 든다

 


 

5) nonce: web2의 락 대신 쓰이는 이유

EOA 트랜잭션에는 nonce가 있습니다.
이 값은 이 계정이 지금까지 보낸 트랜잭션 카운터 같은 값이고, 두 가지를 해결합니다.

1) 순서 보장

  • 같은 계정에서 nonce는 0, 1, 2... 순서로만 유효합니다.
  • 그래서 같은 계정의 상태 변경은 전역 락이 없어도 직렬화됩니다.

2) 재전송/대체

  • 같은 nonce로 더 높은 수수료를 보내면 replaced가 가능합니다.
  • 즉, 동일 슬롯의 트랜잭션을 교체하는 방식입니다.

개발자 감각으로는 이렇습니다.

  • nonce = (account_id, version) 같은 조건부 커밋 키
  • 단, DB처럼 충돌을 거부하고 끝이 아니라 대체(replace) 전략이 얹혀 있다
참고
GCM counter는 같은 키에서 암호화 입력 재사용을 막기 위한 유일성 값이고, Ethereum nonce는 같은 계정의 상태 변경이 중복되거나 순서가 꼬이는 것을 막기 위한 유일성 값이라 둘 다 재사용 방지라는 직관은 공유하지만 대상이 다르다

Ethereum 트랜잭션 nonce는 결제 시스템의 GTID 같은 비즈니스 멱등성 키가 아니라 계정 단위 상태 변경을 직렬화하는 시퀀스 번호로, web2의 낙관적 락에서 version 필드에 더 가깝고 같은 nonce는 교체 가능한 슬롯처럼 동작할 수 있다.

 


 

6) HD 지갑: 키가 하나가 아니라 '트리'인 이유

현대 지갑은 보통 HD(Hierarchical Deterministic) 구조를 씁니다.

  • 하나의 시드(seed)로부터
  • 수많은 개인키/주소를 결정적으로 파생한다

실무에서 이게 중요한 이유는

  • 백업은 시드 한 번으로 끝(니모닉)
  • 계정/주소를 여러 개 만들어도 관리가 된다
  • 개인정보 보호(주소 재사용 회피)에 유리

대표 표준 흐름은 이런 식입니다.

  • BIP-39: 니모닉 문구 → seed 생성
  • BIP-32: seed → 마스터 키 → 키 트리 파생
  • BIP-44: 파생 경로 표준화(m/44'/60'/0'/0/i 등)

여기서 60은 Ethereum 코인 타입입니다.

참고.
HD 지갑은 하나의 시드라는 마스터 키에서 파생 경로라는 네임스페이스를 입력으로 개인키를 결정적으로 생성하는 구조로, web2의 KDF 기반 키 파생이나 테넌트별 키 네임스페이스 분리에 가깝고 단일 백업으로 무한히 키를 늘릴 수 있게 만든다.

 

7) 키 관리 현실: 보안은 '암호'보다 '운영'이 문제다

암호학적으로 ECDSA가 안전해도, 실제 사고는 보통 운영에서 납니다.

  • 니모닉/개인키 유출(스크린샷, 클라우드 메모, 로그)
  • 피싱(서명 유도)
  • 악성 프론트엔드가 다른 내용에 서명시키기
  • 키스토어/프로세스 메모리 탈취
  • 공급망(브라우저 확장, 의존성) 이슈

그래서 지갑은 단순 UI가 아니라 보안 제품입니다.

실무 선택지 감각

  • 핫월렛: 온라인, 자동화 좋음, 위험 큼
  • 콜드월렛: 오프라인, 안전함, 자동화 어려움
  • MPC: 키를 나눠서 서명(개념적으로), 운영 복잡도 증가

PQC를 해본 입장에서 덧붙이면

  • 언젠가 ECDSA가 위험해질 수 있다는 가정은 합리적이지만
  • 당장 제품 보안에서 더 큰 리스크는 키 유출과 서명 피싱인 경우가 많습니다.

 

8) 결론

  • 지갑은 코인 통이 아니라 키 관리 + 서명기다
  • 계정은 로그인 계정이 아니라 주소로 식별되는 상태 주체다
  • 메시지 서명과 트랜잭션 서명은 효과와 책임이 다르다
  • nonce는 계정 단위 직렬화를 제공하고, 대체/재전송의 기반이다
  • 보안은 암호만큼 운영이 중요하다

 

Comments