POSTD PRODUCED BY NIJIBOX

POSTD PRODUCED BY NIJIBOX

ニジボックスが運営する
エンジニアに向けた
キュレーションメディア

POSTD PRODUCED BY NIJIBOX

POSTD PRODUCED BY NIJIBOX

ニジボックスが運営する
エンジニアに向けた
キュレーションメディア

FeedlyRSSTwitterFacebook
Víctor Cuadrado Juan

本記事は、原著者の許諾のもとに翻訳・掲載しております。

この記事は以下のシリーズの一環です

  • ラップトップへのログインと自動的な復号化
  • 保持しているパスワードもしくはセキュリティ情報の暗号化と復号化
  • 暗号化したメールの送受信
  • Webにログインする際の、2段階認証コードの提供
  • モバイルフォンでの上記内容の実施
  • マシン上のsudoに対する認証
  • sshキーのシームレスな管理
  • 各種の初期登録などで使われる、同意の署名

免責事項

もちろん、このガイドで100%のセキュリティが確保できるわけではありませんし、全てを網羅するものでもありません。また、安全保障に関わる政府の諸機関から、目をつけられずに済むという保証もありません。どうか、気軽に学べる趣味という程度に考えてください。結局、この記事は全てセキュリティ侵害についてであり、私は誰もがするように、適当な場所に線を引くことにします。この記事について、不備な点や提案などがありましたら、いつでもご連絡ください。

パート1:エアギャップ・コンピュータ、GPG、スマートカード

このパートでは、以下の内容を取り上げます

  1. エアギャップ・コンピュータのセットアップ
  2. GPGキーとサブキーの作成
  3. パブリックキーの作成
  4. YubiKey NEOを設定し、キーをロードする
  5. キーのバックアップ
  6. YubiKey NEO用に別のコンピュータをセットアップする
  7. オールドキーからの移行
  8. 緊急時におけるサブキーの失効

内容に入る前に、いくつかコンセプトを学んでおきましょう。認証に使われる情報には、3つの異なるタイプがあります。

  • 自分 独自の もの、または自分 だけが 行うこと(例:指紋、生体認証、ユーザ名)
  • 自分 だけが 知っていること(例:南京錠の番号の組み合わせ、パスワード)
  • 自分 だけが 持っているもの(例:金属製の鍵、電話機、2段階認証トークン)

セキュリティ的に最上級である”自分独自のもの”は、少しあいまいです。これは、それ以下の等級である”自分だけが持っているもの”になり得るからです。例えば指紋は本人が使い残した物(プラスチックボトルやカップ)から簡単に入手して、日用品を使って簡単にコピーすることができます。そして、セキュリティが侵害されたとしても変更できません。あるいは、誰かがあなたの手から指を取り去ることができますし、ほとんどのスキャナはそんなことは感知しないでしょう。生体認証が”ユーザ名”としてしか使用されないのはこのためです。これに対して、強固で個人的なパスワードは、使用する際にしか漏れる恐れはありませんし、どこへ行こうと、置き忘れることもありません。

最も包括的な解決方法は、3つの情報を全て使用することでしょう。ご存知のように、2段階認証スキームと呼ばれているものです。自分 独自の ものと、自分 だけが 知っているもの(ログインとパスワード)、そして自分 だけが その瞬間に持っているトークン(一度だけ使用するコード、またはクレジットカードや電話を必要とするデバイスによって生成されるコード)です。攻撃者がセキュリティ侵害を成し遂げるには、対象者のパスワードを推測し、デバイスを盗み出さなければならないでしょう。

自分 だけが 持っているトークンは YubiKey NEO というものになるでしょう。これは小型で耐久性に優れたUSBキーで、静電容量式タッチボタンが1つついています。これを自分のキーホルダーに取り付けたり、より安全にするために常時身につけているブレスレットに取り付けたりします。10年以内に、この種のデバイスが一般的になる可能性はかなり高いでしょう。例えばNFC内蔵リングです。これに、自分のパスワードを記憶させることで、考えうるあらゆるものに、自動的にログインできるのです。

image of Yubikey Neo

YubiKey NEOには、以下のような機能があります。

  • USBによるワンタイムパスワード(OTP)の提供
  • NFCによるOTPの提供。 Yubico 認証アプリ を使ってアンドロイド携帯でも読み出し可能
  • セキュアエレメントとJavaCardに準拠しているので、スマートカードとして機能し、GPGサブキーのセットを収容することが可能。全ての暗号化と復号化はYubiKey内部で行われ、キーの抜き取りは不可能
  • USBによって、静的パスワードを1つだけ提供することも可能

私たちのセキュリティスキームとYubiKeyをセットアップするには、ある基盤が必要です。それがエアギャップ・コンピュータです。

1. エアギャップ・コンピュータ

エアギャップ・コンピュータは、それ自体がインターネット接続しておらず、更に、インターネットにつながる他のいかなるシステムにも接続されていないコンピュータです。こうした目的で使用する場合は、Raspberry PiやBeagleBone Blackなどのボードコンピュータが、大変役立ちます。これらは全てFOSSハードウェアであり、低価格で(高くても約5,400円程度)、携帯可能で(クレジットカードのサイズ)、無線LANチップを内蔵していないので、ネットワークに接続していなければ、(スマートフォンや内蔵のブロードバンドチップとは違って)確実にネットワークから遮断できます。また、コンピュータに組み込まれているmicroSDカードを交換するだけで、異なるエアギャップ・コンピュータとして使用することもできます。保管も楽ですし、エポキシ樹脂による改ざん防止加工もできます。

私は、今持っている Olimex A20 Olinuxino Lime を使おうと考えています。

A20 Olinuxino Lime

マスターGPGキーとサブキーを作成する際に、マスターキーへの署名や、バイナリの構築と署名などをするために、このコンピュータを使うことになります。オフライン・コンピュータへのファイルの書き込み、書き出しには、USBを利用します。こうした操作はあまり行わないので、それほど大きな障害とはならないはずです。

インストール

そのためには、バイナリ・ブロブを排したDebian Jessie(非バイナリ・ブロブのソフトウェア)をインストールします。更にA20 Olinuxino Lime上のシンプルなフレームバッファサポートをインストールします。そうすることにより、HDMIアウトプット上でコンソールを使えます。そのためには、U-Bootブートローダのバージョン2015.01以上と、Linux kernelの3.19以上が必要です。その際、選択肢は2つあります。週次/日次の Debian ARM ISO イメージ を利用するか、自分でインストールを行うかです。

自分でインストールを行う場合は、 Linux-sunxi wiki のSDカードイメージの作成手順に従ってください。(余談ですが、私はこのLinux-sunxi wikiのページにコントリビュートしました)。U-Bootを構築するには、 A20-OLinuXino-Lime_config と、 Olimex A20-OLinuXino-LIME をflash-kernelのデバイス名として使用してください。

システムの実行後、次のパッケージを更新してインストールします(もし将来、新しいパッケージをインストールしたい場合は.debの拡張子のファイルをダウンロードし、USBを使ってインストールする必要があることを覚えておいてください。

# Update the system:
$ sudo apt-get update && sudo apt-get dist-upgrade
# For console and keyboard configuration:
$ sudo apt-get install console-data keyboard-configuration
# For checking GPG keys:
$ sudo apt-get install hopenpgp-tools # as of now, not yet on armhf
# For backing up the keys:
$ sudo apt-get install paperkey qrencode
# For using and configuring the Yubikey:
$ sudo apt-get install python-yubico python-yubico-tools yubikey-personalization
# For smartcards:
$ sudo apt-get install pcscd scdaemon pcsc-tools gpgsm
# Install gnupg2:
$ sudo apt-get install gnupg2
# For encrypted filesystems:
$ sudo apt-get install cryptsetup libpam-mount
# And install the packages you want:
$ sudo apt-get install git zsh tmux vim w3m

将来的には、gnupg2 v2.1以上をインストールすることになります。そうすればいろいろなことがもっと簡単になります。現時点では、Debian Jessieを使うと、次のようになります。

$ aptitude versions gnupg2 scdaemon gpgsm pcscd
Package gnupg2:
   2.0.26-6
Package gpgsm:
   2.0.26-6
Package pcscd:
   1.8.13-1
Package scdaemon:
   2.0.26-6

この openPGP ベストプラクティス・ガイド で勧めているように、堅牢になったJacob Appelbaumのgpg.confを取り込み、読んで内容を理解しましょう。

$ wget https://github.com/ioerror/duraconf/raw/master/configs/gnupg/gpg.conf ~/.gnupg/gpg.conf
# Enable ssh support:
$ echo "enable-ssh-support" >> ~/.gnupg/gpg-agent.conf

これでコンピュータはLANから切り離され、オフラインになりました。もちろん、これ以降は、UARTやsshなどでOlinuxinoと接続してはいけません。コンピュータをHDMIスクリーンと、キーボードに接続します。

使用方法

将来、このコンピュータを再び使う必要がある場合は、次のように、時計を再設定しなくてはなりません。

$ sudo date -s "15 MAY 2015 11:14:00"

もっと良い方法としては、バッテリーとともに、リアルタイムクロックモジュールに接続することです。リアルタイムクロックには、 こちらのリンクでご紹介しているもの や、 こちらでご覧頂けるもの もあります。I2CはKernel3.13以降で使えるので、きちんと動くはずです。他にも多くのモジュールがあり、とても安価です。私たちのコンピュータのSoCボードにはリアルタイムクロックが内蔵されています。ですから、Olinuxinoにバッテリーを接続すれば、時刻情報は維持されています(コントローラはMainline Kernel内にはすでにありませので、少々待つ必要があります)。

コンソールの設定が必要な場合や、現在設定されているものと異なるロケールのキーボードとの接続が必要な場合には、次のように実行します。

$ sudo dpkg-reconfigure console-data
$ sudo dpkg-reconfigure console-setup
$ sudo dpkg-reconfigure keyboard-configuration && service keyboard-setup restart

さあ、これでやっと一息入れて、エアギャップ・コンピュータのセキュリティと実行についてじっくり検討できますね。

image of Olinuxino A20 Lime in the case

2. GPGキーの生成

マスターGPGキーのペアと、サブキーのペアを生成します。もしパブリックキーの暗号化の方法がどんなものか知りたければ、 この映像はとても参考になります 。サブキーについて詳細を知りたい場合は、 サブキーに関するDebianのサイト と、 StackOverflow post を読むことをお勧めします。さあ、いよいよこの再編集版 OpenPGPのベストプラクティス の山場です。マスターキーのペアは他の人のキーに署名する際、そして新しいサブキーを発行する際に使用されます。サブキーはマスターキーにリンクしていて、YubiKey NEOの中に格納されます。これは、暗号化や復号化の際に使用されます。必要ならば更にサブキーのペアをつくることができます。なぜなら、もし紛失したり、セキュリティ侵害を受けたりしても、再度署名を必要としないマスターペアにリンクしているからです。サブキーのペアを生成する際には、YubiKey NEOは2048ビットまでのキーしか格納および処理ができないことを覚えておいてください。

YubiKeyでは4096ビットのマスターキーのペアを作成できない上に、バックアップできるキーペアは3つのサブキーまでなので、エアギャップ・コンピュータ内にキーを生成します。

有効期限は1年で、毎年手動で延長できます( その理由はこちらをご覧ください )。

マスターキーを生成します。

# Generate a new master key:
$ gpg2 --full-gen-key
Your selection? 4 (RSA sign only)
What keysize do you want? (2048) 4096
Key is valid for? (0) 1y

# Add more user ids as desired:
$ gpg2 --edit-key <key id here>
gpg> adduid
# Select your primary uid:
gpg> uid 1
gpg> primary
gpg> save

失効証明書を作成します。

$ gpg2 --output \<your@email.org\>.gpg-revocation-certificate --gen-revoke your@email

マスターキーのバックアップを作成します。

$ gpg2 --export-secret-keys --armor your@email.org > \<your@email.org\>.private.gpg-key
$ gpg2 --export --armor your@email.org > \<your@email.org\>.public.gpg-key
$ mkdir backup-master-keys
$ mv \<* backup-master-keys/

サブキーを生成します。

$ gpg2 --expert --edit-key <key id here>
gpg> addkey
Your selection? 4 (RSA sign only)
What keysize do you want? (2048) 2048
Key is valid for? (0) 1y
gpg> addkey
Your selection? 6 (RSA encript only)
What keysize do you want? (2048) 2048
Key is valid for? (0) 1y
gpg> addkey
Your selection? 8 (set your own capabilities)
Toggle: a,s,e so it is for Authentication
What keysize do you want? (2048) 2048
Key is valid for? (0) 1y
gpg> save

サブキーのバックアップを作成します。

$ gpg2 --export-secret-keys --armor your@email.org > \<your@email.org\>.master-subkeys.gpg-key
$ gpg2 --export-secret-subkeys --armor your@email.org > \<your@email.org\>.subkeys.gpg-key
$ mkdir backup-subkeys
$ mv \<* backup-subkeys/

3. パブリックキーを発行する

キーサーバと自分のWebページに次のコードを入力します。

# On your air-gapped computer:
$ mkdir ~/usb
$ sudo mount /dev/sda1 ~/usb -o uid=1000,gid=1000,rw
$ cp publickey.txt ~/usb/
$ sudo umount /dev/sda1

# On your networked computer:
$ gpg2 --import < /media/8GB/publickey.txt
$ gpg2 --send-keys <key id here>

4. YubiKey NEOの設定

YubiKeyをエアギャップ・コンピュータに接続します。OTPとCCIDの互換性のために、YubiKey内のイジェクトフラグが 82に設定 されていることを確認します。

$ ykpersonalize -m82 # take it out and plug it back to restart it

また、lsusb –vを使ってバージョン3.1.8以降の新しいファームウェアであることも確認してください。更に、 CVE-2015-3298 への脆弱性が改善された新しいYubiKey NEOを必ず使うようにします。CVE-2015-3298に脆弱な古いタイプを持っている場合は、無料で新しいYubiKey NEOへの交換と配送をしてくれるサービスを利用できます(パッチを当てるだけで済む場合でも同様のサービスを受けられます)。

これらの設定が完了したら、次はスマートカードの設定を行います。

$ gpg2 --card-edit
gpg/card> admin
# Change PIN and Admin PIN: (default are 123456 and 12345678 respectively)
gpg/card> passwd
1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit
...
Your selection? 1
PIN changed.
...
Your selection? 3
PIN changed.
...
Your selection? q
# Change the card's info:
gpg/card> name
...
gpg/card> lang
...
gpg/card> sex
...
# Set the url to where your public key is (keyserver, your page, etc):
gpg/card> url
...
gpg/card> login
...
gpg/card> quit

サブキーをスマートカードに移動します(コピーではなく、完全に 移動 してください。同じサブキーを別のYubiKeyで利用したい場合は、以下の例のようにバックアップを取っておく必要があります)。

$ gpg2 --edit-key <key id here>
...
gpg> toggle
...
gpg> key 1 # select 1
...
gpg> keytocard
...
Please select where to store the key:
(1) Signature key
(3) Authentication key
Your selection? 1
...
gpg> key 1 # deselect 1
...
gpg> key 2 # select 2
...
gpg> keytocard
...
Please select where to store the key:
(2) Encryption key
Your selection? 2
...
gpg> key 2 # deselect 2
...
gpg> key 3 # select 3
...
gpg> keytocard
...
Please select where to store the key:
(3) Authentication key
Your selection? 3
...
gpg> save

スタブのバックアップを作ります。

mkdir backup-masterstubs
$ gpg2 --export-secret-keys --armor your@email.org > \<your@email.org\>.master-stubs.gpg-key
$ gpg2 --export-secret-subkeys --armor your@email.org > \<your@email.org\>.subkeys-stubs.gpg-key
$ gpg2 --export --armor your@email.org > publickey.txt
$ mv \<* publickey.txt backup-masterstubs/

YubiKey NEOで指定したURLに~/backup-masterstubs/publickey.txtを加えてください。

これでYubiKeyの設定が完了です! お持ちのキーホルダーに加えたり、私のようにリストバンドに付けてみたりしてください。

image of the yubikey in a wristband

5. バックアップ

USBフラッシュドライブ内のエアギャップ・コンピュータの内部に、主要なキーペアと失効証明をバックアップしなければいけません。

$ sudo mount /dev/sda1 ~/usb -o uid=1000,gid=1000,rw
$ cp backup-* ~/usb/
$ sudo umount /dev/sda1

また、 Paperkey を利用すると、シークレットキーの”秘密の短いコード(secret bits)”が表示されるので、それを手で紙に書き写して保存しておくことも可能です(およそ149バイトのコードが表示されます)。プリンタで印刷する場合は、プリンタのメモリからシークレットキーが漏れてしまう可能性があるので注意してください。この場合もやはり、エアギャップ・コンピュータは安全な場所に保存するべきです。少なくともmicroSDは必ず安全な場所に保存してください。

6. YubiKey NEOを別のコンピュータで使用する

マシンの設定

必要なパッケージをインストールします。

# For smartcards:
$ sudo apt-get install pcscd scdaemon pcsc-tools gpgsm
# Install gnupg2 v2, for Yubikey, and ssh auth compatibility:
$ sudo apt-get install gnupg2

GNOME 3(またはそれをベースにしたデスクトップ環境)を使用している場合は問題が生じます。gnome-keyringのgpg-agentプロトコルの導入が不完全なため、少なくともGPGのスマートカード機能とGPGSMの多くの機能を破損してしまいます。GNOME 3を使わずに、gnome-keyring-daemonを非アクティブ化し、代わりにgpg-agentを利用します。私が最善だと思う解決方法は、 gnupgメール リストで見つけました。

mkdir ~/.config/autostart/
cp /etc/xdg/autostart/gnome-keyring-gpg.desktop ~/.config/autostart/
echo 'Hidden=true' >> ~/.config/autostart/gnome-keyring-gpg.desktop

私の設定をご覧になりたい場合は、私の ドットファイル を確認してください。こちらにはgpg-agentのワークアラウンドや共有可能な設定なども載せています。

パブリックキーをフェッチする

パブリックキーをフェッチし、スタブキーを作成します。

$ gpg2 --card-edit
gpg/card> fetch
    gpg: solicitando clave 0x223F15CA5AAF0E78 de http servidor viccuad.me
    gpg: clave 0xA2591E231E251F36: clave pública "Víctor Cuadrado Juan <me@redacted>" importada
    gpg: Cantidad total procesada: 1
    gpg:               importadas: 1  (RSA: 1)
gpg/card> quit

すると、GPGのプライベートキーの中にスタブを確認できるはずです(sec#の#はスタブで装飾のないキーであることを意味します)。私の場合は以下のようになりました。

$ gpg2 -K
/home/vic/.gnupg/secring.gpg
----------------------------
sec#  4096R/0xA2591E231E251F36 2015-05-13 [caduca: 2016-05-12]
      Huella de clave = E3C5 114C 0C5B 4C49 BA03  0991 A259 1E23 1E25 1F36
uid                            Víctor Cuadrado Juan <me@redacted>
uid                            Víctor Cuadrado Juan <victorcuad@redacted>
ssb>  2048R/0x223F15CA5AAF0E78 2015-05-13
ssb>  2048R/0x7413065A8F779586 2015-05-13
ssb>  2048R/0x3B1500BD8C0124E3 2015-05-13

このキーを究極に信頼できるキーとして指定します。

$ gpg2 --edit-key <your key id here>
gpg> trust
your decision? 5
Do you really want to set this key to ultimate trust? (y/N) y
gpg> quit 

7. オールドキーからの移行

オールドキーセットから、作成したばかりの新しいセットに移行する場合は、新しいキーでオールドキーに署名し、移行の宣言とオールドキーの失効を記述します。また、必要な時に古いファイルを復号できるよう、オールドキーペアもバックアップする方が賢明です。

オールドキーに署名する

オールドキーに署名するために、オールドキーのエクスポート、エアギャップ・コンピュータへの移動、署名、共有を行います。

# On your networked computer:
$ gpg2 --export --armor <old key id here> > oldkey.txt

# Copy oldkey.txt to a USB stick and connect the stick to your air-gapped computer

# On your air-gapped computer:
$ sudo mount /dev/sda1 ~/usb -o uid=1000,gid=1000,rw

# Import the key and sign it:
$ gpg2 --import < ~/usb/oldkey.txt
$ gpg2 --sign-key <old key id here>
Really sign all user IDs? (y/N) y
Really sign? (y/N) y

# Export the old key and copy it to the USB:
$ gpg2 --export <old key id here> > ~/USB/signed-oldkey.txt
$ sudo umount /dev/sda1

# On your networked computer:
$ gpg2 --import < /media/8GB/signed-oldkey.txt
$ gpg2 --send-keys <old key id here>

移行を宣言する

移行の宣言について、 こちらに良い例が掲載されています 。新旧両方のキーを使ってクリアサインし、安定した場所に公開します。お持ちのリファレンスをGPGキーへとアップデートすることも忘れないでください(メールの署名、サイトのAboutページ、名刺などです)。

# On your networked computer:
$ gpg2 --export --armor <old key id here> > oldkey.txt
$ gpg2 --export-secret-keys --armor <your old key id here> > secret-oldkey.txt

# Copy oldkey.txt and your transition statement to a USB stick and
# connect the stick to your air-gapped computer

# On your air-gapped computer:
$ sudo mount /dev/sda1 ~/usb -o uid=1000,gid=1000,rw

# Import the key and sign it:
$ gpg2 --import < ~/usb/secret-oldkey.txt

# Clearsign the statement. Note that we used “<new master key>!" to make GnuPG
# use the master key for signing rather than a subkey, which it would normally do:
$ cat unsigned_GPG_transition_statement_2015-5-15.txt |
gpg --clearsign --personal-digest-preferences "SHA512" --local-user <old key here>
--local-user <new master key>! > GPG_transition_statement_2015-5-15.txt

# Export the old key and copy it to the USB:
$ cp GPG_transition_statement_2015-5-15.txt ~/usb/
$ sudo umount /dev/sda1

# Put the transition statement somewhere public

オールドキーを失効させる

$ gpg2 --edit-key <old key id here>
gpg> revkey # select a reason
gpg> save

# share the revoked key with the key servers:
$ gpg2 --send-keys <old key id here>

8. 緊急時におけるサブキーの失効

サブキーへの不正アクセスや、窃盗、紛失などがあった場合は、サブキーを失効させなければいけません。マスターキーのペアがあるエアギャップ・コンピュータを起動し(もしマスターキーのペアがなければgpg –importを用いてインポートします)、サブキーを失効させます。

$ gpg2 --edit-key <your key id here>
# toggle the subkeys:
gpg> key 1
gpg> key 2
gpg> key 3
gpg> revkey # select a reason
gpg> save

この段階でキーをエクスポートし、キーサーバ上に公開する必要があります。

参考サイト

本記事のマークダウンバージョン

更に詳しく知りたい場合やバックアップのために、本記事のマークダウンバージョンを読みたい場合は こちら からダウンロードできます。

監修者
監修者_古川陽介
古川陽介
株式会社リクルート プロダクト統括本部 プロダクト開発統括室 グループマネジャー 株式会社ニジボックス デベロップメント室 室長 Node.js 日本ユーザーグループ代表
複合機メーカー、ゲーム会社を経て、2016年に株式会社リクルートテクノロジーズ(現リクルート)入社。 現在はAPソリューショングループのマネジャーとしてアプリ基盤の改善や運用、各種開発支援ツールの開発、またテックリードとしてエンジニアチームの支援や育成までを担う。 2019年より株式会社ニジボックスを兼務し、室長としてエンジニア育成基盤の設計、技術指南も遂行。 Node.js 日本ユーザーグループの代表を務め、Node学園祭などを主宰。