尋常でないもふもふ

a software engineer blog

GitHubでEd25519鍵をつかう

TL;DR

  • GitHub 使ってる人のほとんどは RSA 鍵 2048 ビットつかってる
  • でも 2031 年からは強度が弱く非推奨扱い
  • もっと新しい ECDSA 鍵や Ed25518 鍵もあるよ
  • Mac でも対応してるから今すぐ使えるよ

GitHub でもっとも使われている公開鍵暗号方式

多くの人は GitHub のドキュメントに倣って SSH 公開鍵を RSA 鍵 の 2048 ビットで生成してると思います。
Generating a new SSH key and adding it to the ssh-agent - User Documentation

[2017-01-30追記]
執筆当初、上記ドキュメントには -b 4096 のオプションが書かれていなかったので、2048 ビットでみんな生成していたはずです。いつのまにか GitHub 側でこのページにアップデートが入り、完全に安全な 4096 ビットを指定するようにアップデートされてました!

$ ssh-keygen -t rsa -C "your_email@example.com"

2014年7月時点のとある調査によると GitHub ユーザーの 95% は上記のように RSA 鍵の 2048 ビットを利用しているそうです。一方、ECDSA 鍵の利用者はなんと 0.5% …!
GitHubユーザーのSSH鍵6万個を調べてみた - hnwの日記

この 0.5% の人たち、なんと意識の高いことでしょう…!見習いたいものですね。
2014年7月時点では ECDSA 鍵がもっとも意識高かったようですが、2014年12月現在は GitHub で Ed25519 鍵も利用できるため、世界最強度を堅持(顕示)するには Ed25519 鍵を利用するのが必然です(なにしろGitHubの'公開鍵'はその名の通り全世界に公開されているのですから…!)。
GitHub でどの鍵方式が対応しているかは、Settings → SSH Keys → Add SSH Key から、誤った形式で登録してみるとエラーが出るのでわかります。

Key is invalid.
It must begin with 'ssh-ed25519', 'ssh-rsa', 'ssh-dss', 'ecdsa-sha2-nistp256', 'ecdsa-sha2-nistp384', or 'ecdsa-sha2-nistp521'.
Check that you're copying the public half of the key

NIST が推奨する暗号化方式

米国における暗号技術をめぐる動向.pdf
P14〜15 の表によると、2031 年以降、主流の RSA 2048 ビットをはじめほとんどが使用禁止扱いになります。3072 ビット以上を使うか、ECDSA 256 ビット以上が推奨されます。

GitHub が対応している鍵の種類

実質 4 つに対応しています。

  • ssh-rsa(圧倒的多数派のRSA。主流)
  • ssh-dss(DSAのこと。時代遅れ感)
  • ecdsa-sha2-nistp256(ECDSA=楕円DSA。RSAより少ないビット数で暗号強度だせる)
  • ecdsa-sha2-nistp384(同上の384ビット版)
  • ecdsa-sha2-nistp521(同上の521ビット版)
  • ssh-ed25519(Ed25519はECDSAより署名生成/検証のパフォーマンスが良い)

現在つかってる鍵の確認

自分がどの鍵の種類とビット数をつかっているかは ssh-keygen の -l オプションで確認できます。

$ ssh-keygen -l -f ~/.ssh/id_rsa.pub
2048 12:34:56:78:90:ab:cd:ef:12:34:56:78:90:ab:cd:ef  test@test.local (RSA)

この場合、2048 ビットで RSA 鍵ということになります。

2014年12月時点では Mac でつかえませんでした

[追記]
執筆時点の OS X Mavericks 10.9.5 だと、OpenSSH 6.2 なため、ssh-keygen で Ed25519 はおろか、ECDSA すら対応してませんでした。

$ ssh -V
OpenSSH_6.2p2, OSSLShim 0.9.8r 8 Dec 2011
$ ssh-keygen -t ed25519
unknown key type ed25519
$ ssh-keygen -t ecdsa
unknown key type ecdsa

なにやら面倒なことをすればアップグレードできるようですが、面倒なのでやめました。
(例えば brew tap homebrew/dupes することで openssh の 6.6p1 がインストールできるが、これだと ECDSA しか使えないし、元の ssh から切り替えるために面倒な設定が必要)

[追記]
知らないうちに Mac でもできるようになっていました。
手元の環境は OS X El Capitan Version 10.11.5 です。

$ ssh -V
OpenSSH_6.9p1, LibreSSL 2.1.8
$ ssh-keygen -t ed25519
Generating public/private ed25519 key pair.

上記コマンドで Ed25519 の公開鍵と秘密鍵~/.ssh に生成されます。

Ubuntu 14.04でやる

[追記]
執筆時点ではできなかったため、Ubuntuで試してました。

Ubuntu に標準で入ってる openssh なら Ed25519 も対応してるのですぐできます。

$ ssh -V
OpenSSH_6.6.1p1 Ubuntu-2ubuntu2, OpenSSL 1.0.1f 6 Jan 2014

ちなみに CentOS-7.0 は標準だと ECDSA しか対応してません。意識低いですね…。

VirtualBox から起動して試してみます。
Download - Vagrant by HashiCorp から Vagrant をダウンロード&インストールして、任意のディレクトリで vagrant init -m ubuntu/trusty64 すると Vagrantfile が生成されます。これを以下のように修正します(--natdnshostresolver1の前後合わせて3行追加)。これをしないとインターネットに接続できません。

# -*- mode: ruby -*-
# vi: set ft=ruby :

# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box = "ubuntu/trusty64"
  config.vm.provider "virtualbox" do |v|
    v.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
  end
end

書き変えたら vagrant up で起動して vagrant sshUbuntu にログインします。ダウンロード含めても 5 分以内に完了すると思います。
ログインしたら ssh-keygen -t ed25519 -C 'コメント' で生成します。

vagrant@vagrant-ubuntu-trusty-64:~$ ssh-keygen -t ed25519 -C 'jnst@example.jp'
Generating public/private ed25519 key pair.

真に意識高い人ならば -b 521 オプションの追加で最強強度のビット数で生成可能ですが、まぁ必要ないかと。起動した Ubuntuexit した後に、vagranth halt すると終了します。

疎通確認

GitHub 上から公開鍵(~/.ssh/id_ed25519.pub)を登録したら疎通確認します。

$ ssh -T -i ~/.ssh/id_ed25519 git@github.com
Hi jnst! You've successfully authenticated, but GitHub does not provide shell access.

秘密鍵をコピーしてもダメ

Ubuntu で生成した秘密鍵(~/.ssh/id_ed25519)を Mac 上にコピーして使えばいいじゃん!と思ってやってみたけどダメでした。 ssh-v オプションで実行してみると詳細にエラー内容が表示されますが、ed25519 なんて知らねーよと怒られます。サーバ(GitHub)が対応しててもクライアント(Macssh)が対応してないとダメなんですね。
素直に Apple 様の openssh アップデートを待つことにします。だって面倒くさい。

[追記]
Apple 様が OpenSSH のバージョンをあげてくれたので使えるようになりました。やったね!