Dilluti0n의 블로그

pass(1)로 패스워드를 관리하다가 어떤 항목은 복호화가 되고 어떤 항목은 안 되는 현상이 있었다.

gpg: public key decryption failed: Provided object is too large
gpg: decryption failed: Provided object is too large

처음엔 파일이 손상된 것 같아서

$ git fsck --full --strict
Checking ref database: 100% (1/1), done.
Checking object directories: 100% (256/256), done.

로 blob 해시들을 검사해봤는데 문제가 없어서, gpg --list-packets 로 암호화된 파일의 내부 구조를 비교해 봤다.

실패하는 파일:

$ gpg --list-packets ~/.password-store/hskim/mutt@google.gpg
:pubkey enc packet: version 3, algo 1, keyid 4898C1982AD755AE
        data: [4096 bits]

성공하는 파일:

$ gpg --list-packets ~/.password-store/hskim/github.com.gpg
:pubkey enc packet: version 3, algo 1, keyid 4898C1982AD755AE
        data: [4095 bits]

data 필드의 비트 수가 4096 일때만 실패하는 현상이 발생했다.

GPG의 하이브리드 암호화 구조

비대칭 암호화는 보통 느려서, GPG는 먼저 데이터를 대칭키로 암호화(빠름)한 뒤, 그 대칭키를 비대칭키로 암호화한 뒤 암호 파일(.gpg) 에 추가하는 하이브리드 암호화를 사용한다.

.gpg 파일의 구조:

  1. pubkey enc packet — 랜덤으로 생성된 세션키(대칭키)를 수신자의 RSA 공개키로 암호화한 것. data: [4096 bits] 가 이 RSA 암호문의 크기다.
  2. encrypted data packet — 실제 데이터(패스워드)를 세션키로 AES 암호화한 것.

복호화할 때 GPG는 먼저 1번 패킷의 RSA 암호문을 비밀키로 복호화하여 세션키를 꺼내고, 그 세션키로 2번 패킷을 AES 복호화한다.

내 비밀키는 TPM에 바인딩되어 있으므로, 1번 단계에서 GPG는 RSA 암호문을 tpm2daemon 을 통해 TPM 칩으로 보낸다. 여기서 RSA 암호문이 4096 비트일 때 object too large 에러가 나와서 실패했다. (4095 비트일때는 성공)

TPM과 키 구성

내 GPG 키 구성은 다음과 같다:

$ gpg --list-secret-keys
sec#  rsa4096 2025-08-17 [SC]
      3D4686CAC75A49A69E49692099A8DC6DA49AB13C
ssb>  rsa4096 2025-08-17 [E]
      Card serial no. = TPM-Protected
ssb>  rsa4096 2025-09-05 [S] [expires: 2026-09-05]
      Card serial no. = TPM-Protected

ssb> 의 > 는 비밀키가 로컬 디스크가 아닌 외부 장치(여기서는 TPM)에 저장되어 있음을 의미한다. TPM(Trusted Platform Module)은 하드웨어 보안 모듈로, 비밀키가 칩 밖으로 나오지 않아 키 유출 위험을 줄인다.

GnuPG 2.4+에서는 tpm2daemon 이 GPG와 TPM 사이의 통신을 담당한다.

버전 비교

GnuPG 버전을 확인해보니 2.5.17이 설치되어 있었다. 이건 개발 브랜치(unstable)다.

$ gpg --version | head -1
gpg (GnuPG) 2.5.17

2.4.9(안정 버전)로 다운그레이드한 후 동일한 파일을 복호화하면 4096 비트, 4095 비트 모두 정상적으로 성공했다.

# Gentoo에서 2.5.x 마스킹
$ echo ">=app-crypt/gnupg-2.5.0" | sudo tee /etc/portage/package.mask/gnupg
$ sudo emerge -av app-crypt/gnupg

$ gpgconf --kill gpg-agent tpm2daemon
$ pass show hskim/mutt@google
(정상 출력)

GnuPG 2.5.17의 tpm2daemon 이 RSA 4096 암호문을 TPM으로 전달할 때 경계 조건 처리에 버그가 있는 것으로 생각했다.

버그 리포팅

GnuPG의 버그 트래커(dev.gnupg.org)에 계정을 만들려면 메일링 리스트를 통해 요청해야 한다. 번거로운 과정을 거치는 대신 gnupg-devel 메일링 리스트에 직접 버그 리포트를 보냈다. 이 리스트는 개발 논의와 버그 트래킹을 겸한다.

메일링 리스트 구독

먼저 구독이 필요하다. 구독하지 않으면 메일이 승인 대기 상태가 되거나 거부될 수 있다.

To: gnupg-devel-request@gnupg.org
Subject: subscribe

웹에서도 가능하다: https://lists.gnupg.org/mailman/listinfo/gnupg-devel

리포트 작성

메일링 리스트의 규칙에 따라 plain text로 작성했다. HTML 메일, 대용량 첨부, BCC 전송은 거부된다.

리포트에 포함한 내용:

To: gnupg-devel@gnupg.org
Subject: [BUG] tpm2daemon: RSA 4096 decryption fails with
         "Provided object is too large" (regression from 2.4.9)

요약