
TPM 2.0을 사용하는 휴대 가능한 하드웨어 기반 WebAuthn 자격 증명. 마스터 시드에서 파생된 결정론적 부모 키는 여러 기기 간 자격 증명 이식성을 가능하게 합니다. 개인 서명 키는 TPM을 절대 떠나지 않습니다. 브라우저 확장 프로그램과 CLI를 포함합니다.
⚠️ 초기 개념 증명입니다. 이 프로젝트는 철저한 테스트나 감사를 거치지 않았습니다. 실험 외의 용도로 사용하지 마십시오.
TPM 2.0을 사용하여 여러 기기에서 작동하는 휴대용 하드웨어 기반 WebAuthn/패스키 자격 증명입니다.
기존 TPM 자격 증명은 생성된 기기에 고정됩니다. 이 프로젝트는 마스터 시드에서 파생된 결정적 부모 키를 각 기기의 TPM에 가져와서 휴대성을 확보합니다. 하나의 TPM이 암호화한 자격 증명 Blob은 동일한 시드로 프로비저닝된 다른 TPM에서 로드하여 사용할 수 있습니다. 개인 서명 키는 각 자격 증명에 대해 TPM이 무작위로 생성하며, 일반 텍스트로 하드웨어 외부에 존재하지 않습니다.
마스터 시드는 프로비저닝 중에만 기기당 한 번 필요합니다. 이후 모든 암호화 작업은 TPM 내부에서 완전히 이루어집니다.
브라우저 확장 프로그램이 navigator.credentials를 재정의하고 네이티브 메시징을 통해 WebAuthn 호출을 Python 백엔드로 전달하며, 백엔드가 TPM과 직접 통신합니다. 등록 시 TPM은 휴대용 부모 키 아래에 새로운 서명 키를 생성하고 암호화된 Blob을 반환합니다. 인증 시 Blob을 다시 로드하고 내부적으로 복호화한 후 챌린지에 서명합니다.
Linux (Debian/Ubuntu):
sudo apt install tpm2-tools python3-tpm2-pytss python3-cryptography
Windows:
pip install cryptography
Windows는 ctypes를 통해 TBS(TPM Base Services)로 TPM과 통신하므로 추가 네이티브 패키지가 필요하지 않습니다.
브라우저 확장 프로그램은 네이티브 메시징을 통해 native_host.py와 통신합니다. Firefox에 호스트 위치를 알려주는 매니페스트를 등록해야 합니다.
파일 ~/.mozilla/native-messaging-hosts/webauthn_tpm_portable.json을 생성합니다:
{
"name": "webauthn_tpm_portable",
"description": "WebAuthn TPM Portable Credentials Backend",
"path": "/절대/경로/native_host.py",
"type": "stdio",
"allowed_extensions": [
"[email protected]"
]
}
path를 native_host.py의 절대 경로로 바꾸십시오. 실행 가능하게 설정하세요 (chmod +x native_host.py).
Windows에서는 네이티브 메시징 매니페스트가 Windows 레지스트리를 통해 등록됩니다. 자세한 내용은 Firefox 네이티브 메시징 문서를 참조하십시오.
cd extension
npm install
npm run build
그런 다음 Firefox에서:
about:debugging#/runtime/this-firefox를 엽니다.extension/dist 폴더 안의 아무 파일 (예: manifest.json)을 선택합니다.확장 프로그램 팝업을 열고 기존 시드를 붙여넣거나 "Generate"를 클릭하여 새 시드를 생성한 후 "Provision"을 클릭합니다. 새 시드를 생성한 경우 안전한 곳에 저장하십시오. 추가 기기를 프로비저닝할 때 필요하며, 분실 시 새 기기를 설정할 수 없게 됩니다 (이미 프로비저닝된 기기의 기존 자격 증명은 계속 작동합니다).
프로비저닝은 CLI에서도 수행할 수 있습니다:
./webauthn_cli.py provision --generate
# 또는 기존 시드 사용:
./webauthn_cli.py provision <seed_hex>
./webauthn_cli.py test
이 명령은 자격 증명을 생성하고, 챌린지에 서명하며, 서명을 검증합니다.
webauthn_cli.py [--backend=BACKEND] <command> [args]
명령어:
백엔드 (--backend 또는 WEBAUTHN_BACKEND 환경 변수로 선택):
| 백엔드 | 설명 |
|---|---|
tpm | 원시 명령어를 사용한 크로스 플랫폼 TPM (기본값) |
linux | Linux 전용, tpm2-pytss 라이브러리 사용 |
soft | 순수 소프트웨어, TPM 불필요 (테스트용) |
자격 증명 서명 키는 TPM 내부에서 생성되며 일반 텍스트로 TPM 밖으로 나가지 않습니다. 자격 증명 ID의 암호화된 Blob은 프로비저닝된 TPM에 접근할 수 없으면 무용지물입니다. 소프트웨어 기반 자격 증명 저장소와 달리 인증 중에 개인 키가 호스트 메모리에 존재하지 않으므로 콜드 부트 공격 및 악성코드 기반 키 추출로부터 보호됩니다.
TPM2_Duplicate (이론적으로 키를 내보낼 수 있음)는 자격 증명이 빈 authPolicy로 생성되어 차단되므로 전체 시스템 접근 권한이 있어도 복제가 불가능합니다.
프로비저닝된 시스템에서 실행되는 악성코드는 사용자 확인(버튼 누르기 또는 생체 인식)이 없으므로 TPM에 챌린지 서명을 요청할 수 있습니다. 키를 추출할 수는 없지만 활성화된 동안 키를 사용할 수 있습니다. 이는 악성코드가 키를 완전히 탈취할 수 있는 소프트웨어 기반 자격 증명 저장소보다 공격 표면이 좁습니다.
마스터 시드는 신뢰의 근원입니다. 유출될 경우 공격자가 자신의 TPM을 프로비저닝하고 얻은 자격 증명 Blob을 사용할 수 있습니다. 분실하고 모든 프로비저닝된 기기를 사용할 수 없게 되면 자격 증명을 복구할 수 없습니다. 하드웨어 지갑 복구 문구처럼 오프라인 상태에서 안전한 장소에 보관하고, 이상적으로는 여러 위치에 분할하여 보관하십시오.
이 프로젝트는 세 가지 교체 가능한 백엔드를 포함합니다:
**webauthn_tpm_portable.py**는 기본 백엔드입니다. 바이트 수준에서 TPM 명령어를 구성하며 Linux (/dev/tpmrm0)와 Windows (TBS API via ctypes) 모두에서 작동합니다.
**webauthn_tpm_linux.py**는 tpm2-pytss Python 라이브러리를 사용하며 Linux에서만 작동합니다.
**webauthn_soft.py**는 TPM 없이 동일한 자격 증명 형식을 에뮬레이트하는 순수 소프트웨어 구현입니다. 테스트 및 개발에 유용하지만 하드웨어 보호 기능은 제공하지 않습니다.
"/dev/tpmrm0"에 대한 "Permission denied" 오류:
사용자를 tss 그룹에 추가하고 다시 로그인하세요: sudo usermod -aG tss $USER
tpm2-pytss import 오류:
sudo apt install python3-tpm2-pytss 또는 pip install --upgrade tpm2-pytss --break-system-packages를 시도하세요.
확장 프로그램이 네이티브 호스트에 연결되지 않음:
네이티브 메시징 매니페스트의 path가 native_host.py의 절대 경로인지 확인하세요. Firefox에서 브라우저 콘솔 (Ctrl+Shift+J)을 열어 확장 프로그램의 오류를 확인하세요.
MIT
| 명령어 | 설명 |
|---|
status | TPM이 프로비저닝되었는지 확인 |
provision --generate | 무작위 시드 생성 및 프로비저닝 |
provision <seed_hex> | 기존 시드로 프로비저닝 |
create <rp_id> | 신뢰 당사자(Relying Party)에 대한 자격 증명 생성 |
sign <cred_id> <rp_id> <challenge> | 챌린지에 서명 |
verify <cred_id> <rp_id> <challenge> <sig> | 서명 검증 |
clear | TPM에서 휴대용 부모 키 제거 |
test | 전체 생성/서명/검증 주기 실행 |