491 / 736REPRO

Reproducible Firmware Build

재현 가능한 펌웨어 빌드

하드웨어 지갑을 업데이트할 때 설치하는 것은 완성된 파일입니다. 이 파일이 정말 제조사가 공개한 코드로 만들어졌는지는 어떻게 확인할까요? Reproducible Firmware Build는 다른 사람이 같은 소프트웨어를 독립적으로 빌드하고 결과를 비교할 수 있게 합니다. 공개 코드에서 배포된 업데이트까지 이어지는 과정을 확인하는 방법입니다.

펌웨어는 하드웨어 지갑 같은 기기를 작동시키는 소프트웨어입니다. 같은 소스 코드와 지정된 환경, 절차로 미리 정한 파일을 정확히 똑같이 만들 수 있으면 그 빌드는 재현 가능합니다. 프로그램이 같은 방식으로 작동하는 것만으로는 부족합니다. 데이터 자체를 비교하며, 서명된 배포본은 서명을 어떻게 처리할지도 명확해야 합니다.

제조사는 개발자가 읽을 수 있는 코드를 공개할 수 있습니다. 하지만 사용자가 지갑에 설치하는 것은 대개 기계가 처리할 수 있는 형태의 완성된 파일, 즉 바이너리입니다. 두 형태를 잇는 과정이 빌드입니다. 독립적인 사람이 이 과정을 반복한 뒤 배포본과 비교할 수 있습니다. 데이터의 단위인 바이트가 같은지 확인하며, 흔히 내용에서 계산한 지문과 같은 값인 암호학적 해시를 이용합니다. 이 검증은 펌웨어 파일처럼 지정된 결과물에 관한 것이며, 모든 임시 파일과 로그까지 자동으로 포함하지는 않습니다. [1] [4]

두 개발자가 업데이트 하나를 확인한다고 생각해 봅시다. 프로젝트 이름만 알아서는 안 됩니다. 정확한 코드 버전을 지정하는 동일한 commit이 필요합니다. 사용하는 라이브러리와 코드를 기계가 처리할 형태로 바꾸는 도구인 컴파일러의 버전도 알아야 합니다. 컴파일 옵션, 관련 환경 설정, 지갑 모델 역시 절차의 일부입니다. 이 정보는 미리 정하거나 빌드하면서 기록해야 합니다. 그렇지 않으면 두 사람 모두 성실하게 작업해도 결과는 달라질 수 있습니다. [1] [2]

차이가 있다고 해서 누군가 프로그램의 동작을 바꿨다는 뜻은 아닙니다. 컴파일러가 오류 분석용 정보에 작업 폴더의 경로를 넣을 수 있습니다. 두 개발자가 프로젝트를 서로 다른 위치에 저장했다면 파일도 달라질 수 있습니다. 정해진 경로를 쓰거나 지원되는 방식으로 경로를 통일하면 해결할 수 있습니다. 이런 규칙은 사전에 알려진 빌드 절차의 일부여야 합니다. 검증이 실패한 뒤 설명할 수 없는 부분을 지워서 억지로 일치시키면 검증의 의미가 없어집니다. [3]

디지털 서명으로는 해당 파일이 대응하는 키로 생성한 서명과 맞는지 확인할 수 있습니다. 그 키가 제조사의 것이라고 판단하는 일은 신뢰의 또 다른 부분입니다. 재현 가능한 빌드는 다른 질문을 다룹니다. 파일이 지정된 소스 코드에 대응하는지를 확인하는 것입니다. 두 검증은 서로 보완합니다. 다만 공식 업데이트에는 로컬 빌드에 없는 서명 데이터가 들어갈 수 있습니다. 형식을 모른 채 파일 전체를 비교하면 프로그램을 제대로 빌드했어도 차이가 날 수 있습니다. [5]

Trezor 문서는 버전과 모델 선택, 펌웨어 빌드, 공식 파일과의 비교를 설명합니다. 로컬 결과에는 제조사 배포본과 같은 서명이 없으므로 비교 전에 정확히 지정된 서명 필드를 0으로 만듭니다. 오래된 형식은 파일 앞부분에서 정보를 담는 헤더도 다릅니다. 구조는 모델과 버전에 따라 달라지므로 한 기기의 절차를 확인 없이 다른 기기에 적용할 수 없습니다. 원래 서명은 별도로 검증합니다. 조정한 복사본을 비교하는 것은 서명 검증을 대신하지 못합니다. [5]

먼저 같은 코드 버전, 모델, 펌웨어 종류를 비교했는지 확인해야 합니다. 그다음 도구, 라이브러리, 지정된 파일 변환을 살펴봅니다. 원본 파일과 발견한 차이의 기록은 보존해야 합니다. 원인은 환경이나 안내의 오류일 수도 있고, 배포 프로그램에 가해진 변경일 수도 있습니다. 불일치만으로 원인이나 책임자를 알 수는 없습니다. 차이를 설명하고 검증을 다시 마치기 전까지는 검증된 빌드라고 해서는 안 됩니다. [1] [4]

공개 코드에 이미 결함이 있다면 모든 재빌드가 그 결함을 그대로 재현할 수 있습니다. 모두가 사용하는 신뢰할 수 없는 컴파일러가 모든 결과에 같은 악성 변경을 넣을 수도 있습니다. 그 도구를 다시 쓰는 것은 도구 자체를 독립적으로 검증하는 것과 다릅니다. 소스가 공개되지 않은 바이너리 구성 요소도 다시 빌드할 수 있는 범위를 제한합니다. 컴퓨터에 있는 파일이 일치한다고 해서 실제 지갑이 정품인지, 그 펌웨어를 실행하는지도 알 수 없습니다. 파일의 출처를 확인하는 것은 보안의 중요한 일부이지 완전한 증명은 아닙니다. [6] [1]

“검증 완료”라는 보고서는 누가, 어떤 코드 버전을, 어떤 모델용으로, 어떤 절차에 따라 빌드했는지 알 수 있어야 유용합니다. 비교한 파일, 해시 함수, 결과, 서명 데이터를 정확히 어떻게 처리했는지도 밝혀야 합니다. 그래야 다른 사람이 결과를 살피거나 재현할 수 있습니다. 독립적인 검증자가 늘어나면 한 배포자에게 의존하는 정도가 줄어듭니다. 그래도 코드와 업데이트 과정, 기기 자체에 대한 검토는 여전히 필요합니다. [2] [4]

예시 · REPRO

같은 결과 둘과 다른 해시 하나

두 개발자가 같은 코드 버전으로 같은 모델용 펌웨어를 같은 환경에서 빌드합니다. 두 파일의 SHA-256 값은 같지만 서명된 공식 버전의 값은 다릅니다. 문서가 서명 필드를 정확히 정의한다면 복사본에 지정된 변환을 적용하고 다시 비교합니다. 이때 일치한다는 결론은 그렇게 정한 내용에만 해당합니다. 원래 서명은 여전히 별도로 검증해야 하며, 다른 설명되지 않은 차이를 그냥 지워서는 안 됩니다.

더 정확히 이해하려면 이 항목과 함께 다음도 읽어 보세요 Hardware Wallet, Private Key, Cold Storage, Secure Element. 다음 항목에서도 이 글을 참조합니다 COLDCARD RNG Incident (2026).

01사용자가 직접 펌웨어를 빌드해야 하나요?

검증 결과를 이해하는 데 프로그래머일 필요는 없습니다. 다만 독립적인 보고서가 구체적인 버전, 모델, 비교한 파일을 밝히는지 확인하세요. 해시가 같아도 결함이 없다는 증명은 아닙니다. 같은 악성 코드나 컴파일러도 같은 파일을 만들 수 있습니다. 코드 평가와 기기에 대한 신뢰는 별도로 살펴야 합니다.

02서명된 업데이트의 해시가 다르면 공격인가요?

반드시 그렇지는 않습니다. 검증 절차에서 미리 고려한 서명 데이터나 헤더의 차이일 수 있습니다. 버전과 모델, 정확한 절차를 확인해야 합니다. 하지만 설명되지 않은 차이는 검증 성공이 아니며, 데이터를 마음대로 지워서 우회해서도 안 됩니다.

DOC · 001Reproducible Builds — Definition문서 DOC · 002Reproducible Builds — Recording the environment문서 DOC · 003Reproducible Builds — Build paths문서 DOC · 004Reproducible Builds — Build infrastructure threats문서 DOC · 005Trezor — Reproducible build verification문서 DOC · 006Wheeler — Countering Trusting Trust1차 출처
개정일: 1차 출처 우선 · 투자 조언이 아닙니다