YubiKeyを使用したGPGキーの設定ガイド

## はじめに

このガイドでは、YubiKeyを使用してGPG（GNU Privacy Guard）キーを設定する方法を詳しく説明します。GPGは、データの暗号化と署名に広く使用されているオープンソースのツールです。YubiKeyと組み合わせることで、セキュリティをさらに強化し、物理的な二要素認証を実現します。また、GPGエージェントを使用してSSHログインした先でのGit操作にも対応します。

## 前提条件

開始する前に、以下の点を確認してください：

- YubiKeyのファームウェアバージョンを確認する。
  - 古いYubiKeyはed25519暗号化をサポートしていない可能性があります。YubiKeyはファームウェアの更新には対応していないため、ファームウェアが古い場合にはあたらしいYubiKeyを購入してください。
  - 完全な互換性のリストは[firmware compatibility matrix](https://docs.yubico.com/hardware/yubikey/yk-tech-manual/yk5-overview.html#firmware-capability-matrix)を確認してください。
- GPGがインストールされていることを確認する。
- コマンドラインの基本的な操作に慣れていること。

## セットアップ

このセクションでは、GPG鍵の生成と基本的な設定を行います。

まず、環境変数を設定します。これにより、後続のコマンドが正しいディレクトリとアイデンティティを使用することを保証します。

```bash
export GNUPGHOME=~/.gnupg
export IDENTITY="your name <your-name@example.com>"
```

注意: `GNUPGHOME`は通常`~/.gnupg`を使用します。特別な理由がある場合のみ、別のディレクトリを指定してください。

次に、強力なパスフレーズを生成します。このステップは非常に重要です。生成されたパスフレーズは、マスターキーを保護するために使用されます。

```bash
export CERTIFY_PASS=$(LC_ALL=C tr -dc 'A-Z1-9' < /dev/urandom | \
tr -d "1IOS5U" | fold -w 30 | sed 's/./&-/5;s/./&-/11;s/./&-/17;s/./&-/23' | \
cut -c2- | head -1) ; echo -e "\n$CERTIFY_PASS\n"
```

重要: 生成されたパスフレーズは安全な場所に保存してください。このパスフレーズを失うと、鍵にアクセスできなくなります。

キーの種類と有効期限を設定します。RSA 4096ビットは現在のセキュリティ標準に適しています。

```bash
export KEY_TYPE=rsa4096
export EXPIRATION=2y
```

マスターキーを生成します。このキーは証明用（cert）に使用され、有効期限は設定しません。

```bash
gpg --batch --passphrase "$CERTIFY_PASS" \
    --quick-generate-key "$IDENTITY" "$KEY_TYPE" cert never
```

生成されたキーのIDとフィンガープリントを取得します。これらは後続の操作で使用されます。

```bash
export KEYID=$(gpg -k --with-colons "$IDENTITY" | awk -F: '/^pub:/ { print $5; exit }')
export KEYFP=$(gpg -k --with-colons "$IDENTITY" | awk -F: '/^fpr:/ { print $10; exit }')
```

署名、暗号化、認証用のサブキーを生成します。これらのサブキーは日常的な操作に使用され、YubiKeyに保存されます。

```bash
for SUBKEY in sign encrypt auth ; do \
  gpg --batch --pinentry-mode=loopback --passphrase "$CERTIFY_PASS" \
      --quick-add-key "$KEYFP" "$KEY_TYPE" "$SUBKEY" "$EXPIRATION"
done
```

## バックアップ

キーのバックアップは非常に重要です。マスターキー、サブキー、公開鍵のバックアップを作成します。これらは安全な場所に保管してください。

```bash
gpg --output $GNUPGHOME/$KEYID-Certify.key \
    --batch --pinentry-mode=loopback --passphrase "$CERTIFY_PASS" \
    --armor --export-secret-keys $KEYID

gpg --output $GNUPGHOME/$KEYID-Subkeys.key \
    --batch --pinentry-mode=loopback --passphrase "$CERTIFY_PASS" \
    --armor --export-secret-subkeys $KEYID

gpg --output $GNUPGHOME/$KEYID-$(date +%F).asc \
    --armor --export $KEYID
```

重要: これらのバックアップファイルは暗号化されていないため、非常に安全な場所に保管してください。

## 公開鍵のエクスポート

公開鍵を他の人と共有するためにエクスポートします。この鍵は、あなたに暗号化されたメッセージを送信したり、あなたの署名を検証したりするために使用されます。

```bash
gpg --armor --export $KEYID > public/$KEYID-$(date +%F).asc
chmod 0444 public/*.asc
```

注意: `sudo`の使用は環境によっては不要です。ユーザーの権限に応じて適切に調整してください。

## YubiKeyの設定

このセクションでは、YubiKeyの初期設定と鍵の転送を行います。

YubiKeyの現在の状態を確認します。

```bash
gpg --card-status
```

安全なPINを設定します。これらのPINは、YubiKeyでの操作を認証するために使用されます。

```bash
export ADMIN_PIN=$(LC_ALL=C tr -dc '0-9' < /dev/urandom | fold -w8 | head -1)
export USER_PIN=$(LC_ALL=C tr -dc '0-9' < /dev/urandom | fold -w6 | head -1)

gpg --command-fd=0 --pinentry-mode=loopback --change-pin <<EOF
3
12345678
$ADMIN_PIN
$ADMIN_PIN
q
EOF
```

重要: 生成されたADMIN_PINとUSER_PINは安全な場所に保存してください。これらのPINを忘れるとYubiKeyをリセットする必要があります。

YubiKeyを再接続し、PINのリトライ回数を設定します。これにより、ブルートフォース攻撃からの保護が強化されます。

```bash
ykman openpgp access set-retries 5 5 5 -f -a $ADMIN_PIN
```

YubiKeyの属性を設定します。これにより、YubiKeyに個人情報が関連付けられます。

```bash
gpg --command-fd=0 --pinentry-mode=loopback --edit-card <<EOF
admin
login
$IDENTITY
$ADMIN_PIN
quit
EOF
```

## サブキーの転送

生成したサブキーをYubiKeyに転送します。これにより、YubiKeyが実際の暗号操作を行うことができるようになります。

```bash
gpg --edit-key $KEYID
key 1
keytocard
1
save

gpg --edit-key $KEYID
key 2
keytocard
2
save

gpg --edit-key $KEYID
key 3
keytocard
3
save
```

## YubiKeyの使用

公開鍵をインポートし、信頼度を設定します。これにより、システムがあなたの鍵を信頼するようになります。

```bash
gpg --import public/*.asc
gpg --edit-key ${KEYID}
trust
5
y
save
```

## GPGエージェントの転送設定

このセクションでは、リモートマシンでのGit commit署名など、リモート操作のためにGPGエージェントの転送を設定します。

### ローカルマシンの設定

SSHの設定を行い、GPGエージェントのソケットを転送します。`~/.ssh/config`に以下を追加します：

```
Host ${HOST_NAME}
  User ${USERNAME}
  Port 2222
  StreamLocalBindUnlink yes
  RemoteForward /run/user/0/gnupg/S.gpg-agent /Users/${LOCAL_USER_HOME}/.gnupg/S.gpg-agent
```

### リモートマシンの設定

GPGエージェントの設定ファイルをダウンロードします。

```bash
cd ~/.gnupg
wget https://raw.githubusercontent.com/drduh/config/master/gpg-agent.conf
```

公開鍵をリモートマシンに転送します。

```bash
scp ~/.gnupg/pubring.kbx remote:~/.gnupg/
```

`~/.gnupg/gpg-agent.conf`ファイルを適切に設定し、PINエントリーやSSHサポートなどの動作を制御します。以下は例です：

```
pinentry-program /usr/bin/pinentry-curses
enable-ssh-support
ttyname $GPG_TTY
default-cache-ttl 60
max-cache-ttl 120
```

注意: `pinentry-program`のパスは使用するOSによって異なります。上記はLinux用の例です。macOSの場合は`/opt/homebrew/bin/pinentry-mac`、Windowsの場合は適切なパスに変更してください。

#### リモートマシンでのGit設定

リモートマシンでGPG署名付きのコミットを行うためには、`.gitconfig`ファイルを適切に設定する必要があります。

### GPGキーIDの確認

以下のコマンドを使用して、あなたのGPGキーIDを確認します：

```bash
gpg --list-secret-keys --keyid-format LONG
```

このコマンドの出力から、"sec" で始まる行を探し、スラッシュの後ろの16文字の文字列がキーIDです。例えば：

```
sec   rsa4096/0x58D8576394B9513F 2024-07-07 [C]
```

この例では、`0x58D8576394B9513F` がキーIDです。

### .gitconfigの設定

確認したキーIDを使用して、以下の設定をリモートマシンの`~/.gitconfig`ファイルに追加してください。

```ini
[user]
        email = you@example.com
        name = you
        signingkey = 0x58D8576394B9513F  # ここに確認したキーIDを入力
[safe]
        directory = /home/your/project
[commit]
        gpgsign = true
```

この設定により、リモートマシンでGPG署名付きのGitコミットが可能になります。

設定後、以下のコマンドでGPG署名が正しく機能しているか確認できます：

```bash
git commit -S -m "Test signed commit"
git log --show-signature
```

署名付きコミットが正常に作成され、署名が検証できることを確認してください。

## デバッグ

問題が発生した場合のデバッグ方法です。

GPGエージェントを再起動します：

```bash
gpgconf --kill gpg-agent
gpg-agent --daemon
```

エージェントソケットのパスを確認します：

```bash
gpgconf --list-dirs agent-socket
```

詳細なデバッグ情報を得るために、GPGエージェントをデバッグモードで起動します：

```bash
pkill gpg-agent; gpg-agent --daemon --no-detach -v -v --debug-level advanced --homedir ~/.gnupg
```

## 定期的なメンテナンス

セキュリティを維持するために、以下の定期的なメンテナンスを行うことをお勧めします：

1. バックアップの更新：少なくとも年に1回はバックアップを更新してください。
2. 鍵の有効期限の確認：有効期限が近づいている場合は、更新を検討してください。
3. PINの定期的な変更：少なくとも年に1回はYubiKeyのPINを変更してください。
4. ファームウェアの更新：YubiKeyのファームウェアに更新がある場合は、適用を検討してください。

以上で、YubiKeyを使用したGPGキーの設定が完了します。この設定により、高度なセキュリティを実現し、暗号化、署名、認証の機能を安全に利用できるようになります。

## chaetsheet

公開鍵の表示

```
gpg --export -a you@example.com
```