12편 중 9번째 글읽는 데 4분

브라우저 지갑 없이 dApp 쓰기

웹사이트는 브라우저 안에 지갑이 있기를 기대해요. 그런데 브라우저는 컴퓨터에서 가장 노출된 프로그램이에요. AirNox는 페이지에는 지갑처럼 보이지만 아무것도 갖고 있지 않은 확장 프로그램으로 이 문제를 풀어요.

모서리에 키 없는 확장 프로그램 배지가 붙은 브라우저 속 스왑 페이지, 데스크톱 지갑으로 이어지는 로컬 연결, 에어갭(air gap), 그리고 휴대폰
확장 프로그램은 전달하고, 데스크톱은 결정하고, 휴대폰은 서명해요.
목차

지갑이 아닌 확장 프로그램

AirNox 브라우저 확장 프로그램(browser extension)은 탈중앙화 애플리케이션이 찾는 표준 인터페이스를 주입해요. EVM 네트워크용 EIP-1193과 EIP-6963, TON Connect, 그리고 Solana와 Sui 지갑 표준이에요. 페이지 입장에서는 이게 지갑이에요. "어떤 계정이 있나요", "어떤 체인인가요", "이거 서명해 주세요" 같은 요청에 평소처럼 응답해요.

속을 들여다보면 그냥 전달자예요. 키도 없고, 시드(seed)도 저장하지 않고, 아무것도 서명할 수 없어요. 페이지가 보내는 모든 요청은 로컬 전용 채널을 통해 데스크톱의 AirNox Wallet으로 전달되고, 응답도 같은 길로 돌아와요. 내일 이 확장 프로그램이 악성 복제본으로 바뀌더라도, 훔칠 것도, 서명에 쓸 것도 없어요.

기존 확장 프로그램 지갑의 문제

기존 방식의 Web3 지갑은 키까지 포함해 전부 브라우저 안에 있어요. 그러면 키가 컴퓨터에서 가장 노출된 프로그램 안에 놓이게 돼요. 페이지에 주입된 코드가 확장 프로그램의 인터페이스에 닿을 수 있어요. 저장된 비밀 정보는 최신 그래픽카드로 대규모 무차별 대입(brute force)이 가능한 암호화로 보호돼요. 트래커와 광고가 들어 있는 경우가 많아요. 수신 주소 바꿔치기를 조금이라도 막아 주는 경우는 드물어요. 게다가 그 대가로 하루 종일 메모리와 프로세서 시간을 잡아먹어요. AirNox는 브라우저에는 전달자만 남기고, 중요한 건 모두 브라우저 밖으로 옮겨요. 네이티브 데스크톱 프로그램으로, 그리고 AirGap 모드에서는 절대 온라인에 연결되지 않는 휴대폰으로요.

로컬 전용

확장 프로그램과 데스크톱 사이의 채널은 컴퓨터 밖으로 절대 나가지 않아요. 중계 서버도, 클라우드 세션도, 계정도 없어요. 양쪽이 서로를 인증하기 때문에, 지갑인 척하는 프로그램은 아무것도 얻지 못하고, 확장 프로그램인 척하는 페이지도 아무것도 얻지 못해요.

권한은 데스크톱이 관리해요

권한은 브라우저가 아니라 AirNox Wallet에 있어요. 권한은 출처(origin)별, 체인별로 하나씩 부여되고, 암묵적으로 따라오는 권한은 없어요. Ethereum 계정을 볼 수 있게 허용한 사이트라도 Polygon 계정까지 볼 수 있는 건 아니에요. 한 지갑에서 허용한 사이트라도 다른 지갑에서는 허용되지 않은 상태예요.

출처와 체인을 교차한 격자에 허용과 미허용 표시, 그리고 모든 요청이 거부되는 지갑 잠김 행
출처별, 체인별, 기본 차단(fail-closed).

출처는 페이지가 함께 보낸 문자열이 아니라 브라우저가 확인해 준 값이에요. 페이지가 다른 사이트인 척할 수 없어요. 그리고 시스템 전체가 기본 차단(fail-closed) 방식이에요. 명시적으로 허용하지 않은 건 모두 거부하고, 지갑이 이해하지 못하는 요청도 거부해요.

잠겨 있으면 무조건 거부

지갑이 잠겨 있는 동안 확장 프로그램은 요청이 어떤 식이든 아무것도 응답하지 않아요. 페이지는 지갑을 깨울 수도, 계정 목록을 알아낼 수도, 잠금이 풀리면 실행될 서명을 대기열에 넣어 둘 수도 없어요. 잠금은 지갑 안에서 직접 풀어야 하고, 그래야만 브라우저가 응답을 받아요.

서명

트랜잭션, 메시지, 구조화 데이터(typed data) 모두 같은 경로를 거쳐요. 데스크톱이 먼저 요청을 디코딩하고 검사해서, 표준 작업은 알아보고 닮은꼴, 무제한 허용량(unlimited allowance), 알 수 없는 승인 대상(spender)은 경고로 표시해요. AirGap 모드라면 서명되지 않은 요청이 휴대폰으로 건너가고, 거기서 바이트로부터 다시 디코딩돼 화면에 표시된 뒤, Accept(수락)를 눌러야만 서명돼요. 서명이 돌아오면 데스크톱이 브로드캐스트하고, 페이지는 트랜잭션 해시를 받아요. 체인 전환도 같은 방식으로 처리되고, 전환을 허용할지는 지갑이 결정해요.

시드가 데스크톱에 있는 지갑이라면, 같은 검사를 거친 뒤 휴대폰 대신 지갑 창에서 데스크톱이 서명해요.

변조된 페이지가 할 수 있는 것과 없는 것

변조된 페이지나 브라우저 안의 오염된 스크립트는 거짓말을 할 수 있어요. 트랜잭션 하나를 보여 주고 다른 걸 요청할 수 있어요. 클레임을 인증인 척 꾸밀 수도 있어요. 하지만 서명은 할 수 없어요. 결정은 키가 있는 곳에서, 휴대폰이 디코딩한 요청을 직접 읽은 뒤에 내려져요. 브라우저 팝업이라면 그냥 지나쳤을 드레이너(drainer)의 승인 요청도, 휴대폰에는 있는 그대로 나타나요. 이 승인 대상에게, 이 금액만큼 주는 허용량이라고요. 무제한이라면 휴대폰이 그렇게 알려 줘요.

저희가 원한 균형이 바로 이거예요. 페이지에는 브라우저 지갑의 편리함을 주고, 사용자에게는 그 노출 위험을 하나도 남기지 않는 것.

시리즈 목차

  1. 컴퓨터는 이미 감염됐다고 가정하세요
  2. Mass Adoption Security: 서명 기기는 이미 가진 휴대폰이에요
  3. 에어갭을 건너는 세 가지 방법: QR 코드, Bluetooth LE, NFC
  4. 전파에 드러나지 않기: 아무도 스캔으로 찾을 수 없는 서명 기기
  5. 전송 수단은 절대 신뢰하지 않아요
  6. 휴대폰이 보여 주는 것: 서명 기기에서 하는 트랜잭션 분석
  7. 휴대폰은 자기만의 기록을 남겨요
  8. 데스크톱의 금고: Argon2id와 추측에 강한 프로필
  9. 브라우저 지갑 없이 dApp 쓰기
  10. 규칙이 있는 MCP 서버: 한도 안에서 움직이는 AI 에이전트
  11. 모든 걸 담은, 보호받는 지갑 하나
  12. 작고 네이티브하게: C++, JavaScript 런타임 없이, 워크스테이션부터 Raspberry Pi까지

사전 등록

이메일을 남기면 출시 소식을 보내 드려요. 그 밖의 메일은 보내지 않아요.