こんにちは、Juntechです。
今回はSSHの「公開鍵認証」について解説してみようと思います。

実はこのブログでも既に一度登場している公開鍵認証。

【マージするだけ】GitとJenkinsでWPリリースを自動化する〜その2【鍵交換ってやつ】

今回は、
そもそも公開鍵認証って何なの?
何でパスワードより安全なの?
といった疑問を解決したいと思います!

…ちなみに公開鍵認証自体はいろんな方式があり、
今回はあくまでも一般的なSSH(SSH2)での公開鍵認証についての解説です。

公開鍵認証とは

サーバー間通信で使う認証方式

公開鍵認証とは、サーバー間の通信で使われる認証方式の1つです。
サーバー間通信というのは、
例えばsshコマンドで他のパソコンを操作したり、
sftpコマンドで他のパソコンにファイルを送ったりといったものです。

これらの通信ではパスワードを使ってログインすることもできますが、
パスワードは人が覚えて使うケースが多いためバレやすく、
またクライアント・ホスト間でパスワードを共有する必要があるため、
横取りされるリスクもあります。

そこで考えられたのが、2つの鍵を作り、横取りされても大丈夫な鍵だけをやりとりするという公開鍵認証方式です。

ざっくり仕組み

この認証方式では、
クライアントPCが公開鍵・秘密鍵と呼ばれる2つの鍵を生成し、
サーバPCに公開鍵のみを渡して登録してもらいます。
これにより、クライアントは秘密鍵を使うことでユーザ認証を行うことができます。

下記が、公開鍵認証を使ったSSH接続のざっくり流れです。

長々としてますが、ほとんどはSSHの流れです。
署名作成・検証の部分が、いわゆる公開鍵認証です。

公開鍵・秘密鍵のペアには、
公開鍵で暗号化したデータを秘密鍵でしか復号できない、
という性質があります。
これを利用して、秘密鍵で複合処理(署名)を行って公開鍵で検証する、というのが公開鍵認証です。

ちなみにこの処理の前段で鍵交換だとかホスト鍵だとかという言葉が出てきていますが、
これら自体はパスワード認証でも(SSHであれば)使われます。

この認証方式は人が覚えて使うパスワード認証に比べるとより流出しにくく、
またクライアント側で生成してサーバー側で登録するという方式のため、
クライアントが秘密鍵の受け渡しをしない限りは使い回しの心配がありません。

こういった観点から公開鍵認証はパスワード認証よりもセキュアな方式として、
企業間のファイル送受信にも使われたりしています。

電子署名アルゴリズムあれこれ

鍵ペアの生成・署名・検証で使うアルゴリズムにはいくつか種類があります。

RSA

一番有名なのがRSAだと思います。

これは発明者の頭文字をとって付けられた名前だそうですが、
元々は暗号化のアルゴリズムです。

詳しい説明は省きます(というか私も知らない、、)が、
要は鍵生成・暗号化・複合化の数式を応用した電子署名です。

業務で公開鍵認証を使ったときも毎回RSAキーでやりとりしていました。

DSA

次に有名なのがDSAだと思います。

これはDigital Signature Algorithmの略で、
れっきとしたデジタル署名の方式です。

SSH2が登場した頃、RSAが特許の都合で使えず、
こちらの署名方式がスタンダードとなったようです。

鍵の長さ(ビット長)に上限があることから、
強度の面ではRSAの方が強いです。

そのためRSAの特許が切れてSSH2でも使えるようになってからは、
非推奨となってしまっているようです。

ECDSA

DSAを応用してより強度を増した署名方式が、ECDSA()です。

ECとはElliptic Curve(楕円曲線)の略で、
和訳すると楕円曲線電子署名アルゴリズムということになります。

いよいよよくわからんですが、
DSAに比べてビット超が短いわりに、強度はRSAよりも高く、認証速度も早いそうです。

比較的新しめの方式のため使える場面は限られていますが、
今後の活躍が期待できそうですね。

使ってみよう

ということで今回はRSA方式を使った公開鍵認証をやってみたいと思います。

使うのは、MacBookとLinuxサーバです。
Linuxサーバには既にパスワード認証でSSH接続を確認しており、
そのためホスト鍵も登録済みです。

今回はMacBookAirで公開鍵・秘密鍵のペアを作成し、
公開鍵認証でサーバにSSHしてみます。

鍵ペアを生成

まずはMacBookで鍵ペアを生成します。

$ssh-keygen -t rsa

鍵のパス/ファイル名とパスワードを求められるため、
それぞれ入力します。
パスワードは入力しなければ無しで使えるようになります。

Generating public/private rsa key pair.
Enter file in which to save the key (/Users/juntech/.ssh/id_rsa): /Users/juntech/.ssh/id_rsa_centos_k320
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /Users/juntech/.ssh/id_rsa_centos_k320.
Your public key has been saved in /Users/juntech/.ssh/id_rsa_centos_k320.pub.

生成された鍵を見に行きます。

$ cd ~/.ssh
$ ls -lA
total 24
-rw-------   1 juntech  staff  2635  5  1 15:53 id_rsa_centos_k320
-rw-r--r--   1 juntech  staff   593  5  1 15:53 id_rsa_centos_k320.pub
-rw-r--r--   1 juntech  staff   737  4 26 19:41 known_hosts

末尾に.pubとついているものが公開鍵、拡張子なしが秘密鍵です。
ちなみにknown_hostsが、
ホスト認証で使用するホスト鍵を保管しているファイルです。

公開鍵をホストに登録

sftpで、生成した公開鍵をホストに配布します。

$ sftp juntech@192.168.100.201
juntech@192.168.100.201's password:
Connected to 192.168.100.201.
sftp> put ./id_rsa_centos_k320.pub .ssh/
Uploading ./id_rsa_centos_k320.pub to /home/juntech/.ssh/id_rsa_centos_k320.pub
./id_rsa_centos_k320.pub                                                                                               100%  593    60.1KB/s   00:00    
sftp> exit

次にホストへSSHし、公開鍵を登録します。

$ ssh juntech@192.168.100.201
juntech@192.168.100.201's password: 
[juntech@localhost ~]$ cd .ssh/
[juntech@localhost .ssh]$ ls -lA
total 4
-rw-r--r--. 1 juntech juntech 593  5月  6 03:40 id_rsa_centos_k320.pub
[juntech@localhost .ssh]$ cat id_rsa_centos_k320.pub >> authorized_keys
[juntech@localhost .ssh]$ chmod 600 authorized_keys
[juntech@localhost .ssh]$ ls -lA
total 8
-rw-------. 1 juntech juntech 593  5月  6 03:44 authorized_keys
-rw-r--r--. 1 juntech juntech 593  5月  6 03:40 id_rsa_centos_k320.pub
[juntech@localhost .ssh]$ exit

これで公開鍵の登録ができました。

ちなみに今回は丁寧にやりましたが、
MacBook(クライアント)から下記コマンド一発でも登録できます。

cat ~/.ssh/id_rsa_centos_k320.pub | ssh juntech@192.168.100.201 'cat >> .ssh/authorized_keys && chmod 600 .ssh/authorized_keys'

接続してみる

秘密鍵を指定して接続してみます。

$ ssh -i ~/.ssh/id_rsa_centos_k320 juntech@192.168.100.201
[juntech@localhost ~]$

ログインできました!

このままだとパスワード認証も使えてしまうので、
ホスト側のsshd_configを編集してパスワードを無効化にしておくのがおすすめです。

sudo vi /etc/ssh/sshd_config

PasswordAuthenticationの設定値をnoにすることで無効化できます。
sshd_configを編集したら、下記コマンドでsshdを再起動して設定を反映させます。

sudo systemctl restart sshd

今回はここまで。

公開鍵認証は使い方だけ知っていれば特に困る事もないですが、
それだけに中身を説明してと言われるとなかなか難しいです。

今回は勉強も兼ねて扱ってみましたが、
思った以上に込み入ってて時間がかかってしまいました。。

ネットの情報だけだと散らばっていて大変だったので、
もっと詳しく知りたい!という方は書籍も読んでみるといいかもしれません。