SSHで公開鍵認証
本記事では、SSHで公開鍵認証を設定する方法と、公開鍵認証の仕組について説明します。
【以下、2023年1月25日改訂】
1.前提
SSHクライアントホストには、SSHクライアントソフト(OpenSSH)がインストールされている必要があります。
最近のWindows10や、UbuntuにはOpenSSHが最初からインストールされています。
古いWindows10にはOpenSSHがインストールされていないことがあるようです。その場合はOpenSSHをインストールする必要があります。
以下、コマンド操作におけるファイルパス表記はLinux表記で記載します。
Windowsの場合、gitクライアントソフトをインストールすると、git bashが一緒にインストールされます。git bashは、WindowsOSの操作にlinuxコマンドが利用できるbashエミュレータソフトです。まだgitクライアントソフトをインストールしていない場合は、gitクライアントをインストールすることをお勧めします。
2.公開鍵認証設定
2.1.公開鍵認証設定のステップ
SSH公開鍵認証の設定のステップは以下のとおりです。設定はSSHクライアントホストから行います。
1.SSHの公開鍵/秘密鍵の鍵ペアを作成する
2.公開鍵をSSHサーバに登録する
3.接続先SSHサーバの設定追加
4.SSHサーバへの接続
2.2.鍵ペアを作成する
ssh-keygenコマンドでSSH公開鍵/秘密鍵の鍵ペアを作成し、~/.sshフォルダ配下に保存します。"~/.ssh"は、SSHの接続設定を保存するフォルダです。
ssh-keygenは対話式のコマンドです。このコマンドで秘密鍵のファイル名とパスフレーズを設定します。
秘密鍵ファイルのデフォルトファイル名はid_rsaです。ファイル名を指定しなければid_rsaというファイル名で秘密鍵が保存されます。
秘密鍵のパスフレーズは、秘密鍵の暗号化/復号化キーとして利用されます。秘密鍵のパスフレーズを設定しない場合、秘密鍵は平文で保存されます。秘密鍵にパスフレーズを設定した場合、パスフレーズで暗号化された秘密鍵が保存されます。また、公開鍵認証する際、秘密鍵パスフレーズを入力して秘密鍵ファイルの中身を復号化する必要があります。
以下、秘密鍵ファイル名を"ogs-digilife"としたの場合の入力例です。
$ cd ~./.ssh
$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (~/.ssh/id_rsa): ogs-digilife
Enter passphrase (empty for no passphrase):<秘密鍵パスフレーズ>
Enter same passphrase again:<秘密鍵パスフレーズ>
Your identification has been saved in ogs-digilife
Your public key has been saved in ogs-digilife.pub
The key fingerprint is:
SHA256:T/ofg4trxq7zGdZX0vXwI0ecbGKREoVy5vQmBelKV5A hiwas@DESKTOP-8K50I8Q
The key's randomart image is:
+---[RSA 3072]----+
| +Oo. |
| . E ++ .|
| B =o.*.|
| . =.+++.|
| S + +.ooo|
| * . oo .|
| .+ + + |
| ..+= o o |
| .B*.o.. |
+----[SHA256]-----+
公開鍵は、秘密鍵と同じフォルダ(ここでは~/.ssh)に、
<秘密鍵ファイル名>.pub
のファイル名(ここではogs-digilife.pub)で保存されます。
公開鍵認証では、id/password認証のように、サーバと秘密鍵のやりとりをしません。公開鍵で暗号化されたデータは秘密鍵でのみ復号化できる数学的な性質を使って認証を行います。
2.3.公開鍵をsshサーバに登録する
上記で作成した鍵ペアの、公開鍵の方をSSHサーバに登録します。SSHサーバへの公開鍵登録は、SSHクライアントホストからssh-copy-idコマンドを実行するだけです。
コマンド形式)
$ ssh-copy-id -i <公開鍵のファイルパス> <sshサーバのユーザ名>@<sshサーバホスト>
実行例)
SSHサーバにはじめて接続する場合は、本当に接続してよいか、ときかれます。この場合は、yesと入力してください。
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
$ cd ~/.ssh
$ ssh-copy-id -i ogs-digilife.pub ogs-digilife@192.168.0.143
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "ogs-digilife.pub"
The authenticity of host '192.168.0.143 (192.168.0.143)' can't be established.
ED25519 key fingerprint is SHA256:RImJDZXXJWvwRVOZ6btaPEw45X0cwy8//1xfvoYIyu8.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
ogs-digilife@192.168.0.143's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'ogs-digilife@192.168.0.143'"
and check to make sure that only the key(s) you wanted were added.
補足1)
鍵ペアは複数のサーバで共有することができます。ssh-copy-idコマンドを使って複数の接続先SSHサーバに同じ公開鍵を登録します。
補足2)
linuxの場合、秘密鍵ファイルはchmodコマンドを使って管理者権限でのみ、read/writeできる設定にする必要があります。
秘密鍵ファイルを別のSSHクライアントホストにコピーして、別ホストでも同じ鍵ペアを利用することができます。ただし、秘密鍵漏洩のリスクが高くなるので秘密鍵の管理には注意が必要です。
補足3)
SSHではクライアントによるサーバ認証も行っています。SSHクライアントは、初めてSSHサーバに接続する際、接続先SSHサーバのfingerprint(サーバを識別するためのデータ)を取得します。
安全で良いのですが、同じIPでサーバを作り直したりすると、なりすましと勘違いされて作り直したSSHサーバに接続できなくなってしまいます。そのような場合は、SSHクライアントに記録されたサーバのfingerprintを消すか、もしくはSSHサーバ接続時にサーバ認証しないオプションで接続する必要があります。
2.4.接続先SSHサーバの設定追加
接続先SSHサーバの設定を追加しておくと、接続が簡単になって便利です。~/.ssh/configに、以下の書式で設定を追加します。sshサーバのエイリアス名は、SSH接続時に指定します。
書式)
Host <sshサーバのエイリアス名>
User <sshサーバのユーザ名>
Hostname <sshサーバホスト>
IdentityFile <秘密鍵ファイルのパス>
ServerAliveInterval 60
HostとHost設定の各項目は、インデント(行の開始位置)で区別されますので、上記書式のように、インデントを分ける必要があります。
設定例)
Host django03
User ogs-digilife
Hostname 192.168.0.143
IdentityFile C:\Users\ogs-digilife.ssh\ogs-digilife
ServerAliveInterval 60
接続時のSSHクライアントによるサーバ認証をスキップしたい場合は、設定に以下の2行も追加します。
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
2.5.SSHサーバへの接続
~/.ssh/configに接続先設定をすると、エイリアス名で簡単に接続できるようになります。
書式
$ ssh <sshサーバのエイリアス名>
3.公開鍵認証について
公開鍵認証は、SSLによるサーバなりすまし防止、ICカードの偽造防止、デジタル署名を使ったコンテンツの改ざん防止、api認証など、いろいろなところで応用されています。
公開鍵認証は、公開鍵暗号アルゴリズムの以下の特徴を利用しています。
・公開鍵で暗号化したデータを復号できるのは、ペアとなる秘密鍵のみ
(秘密鍵で暗号化したデータを復号できるのは、ペアとなる公開鍵のみ)
・桁数の十分に大きな鍵を使えば、総当りで方式で公開鍵のペアとなる秘密鍵を割り出すのは、天文学的な時間がかかる。
・秘密鍵を所有しているのは、認証される人やモノ(本人)のみ。
・公開鍵で暗号化されたデータを正しく復号できるのは、秘密鍵を所有する本人のみ。
公開鍵暗号アルゴリズムには、いくつか種類があります。SSHではRSA暗号アルゴリズムがよく用いられています。
4.SSH公開鍵認証のシーケンス
SSH公開鍵認証の認証シーケンスを下図に示します。SSHの公開鍵認証では、SSHサーバがSSHクライアントを認証するだけでなく、SSHクライアントがSSHサーバのなりすましもチェックしています。下図は、SSHサーバがSSHクライアントを認証する部分のみ抜き出したものです。

図1 SSHユーザの認証シーケンス
5.ハッシュアルゴリズムについて
図1の中で出てくる、ハッシュ化について補足します。ハッシュ化とは、ハッシュ関数を使って入力値を別の値に変換することを言います。
ハッシュ関数は公開鍵認証でも利用されており、SHA(Secure Hash Algorithm)というアルゴリズムがよく利用されています。SHAは、パスワード管理の際、平文パスワードのスクランブル変換でもよく利用されています。また、LinuxOSのパスワード管理でも、SHAが使われています。
これらは、SHAの以下の特徴を応用したものとなります。
(1)入力値が同じであれば、出力値(ハッシュ値)も同じになる。
(2)入力値の大小に関わらず、ハッシュ値の桁数を揃えることができる。
(3)ハッシュ値から入力値を計算することができない。
(逆関数が存在しない)
(4)入力値が少しでも変わると、ハッシュ値はランダムに変わる
以上の特徴から、巨大なコンテンツでも、例えば512bitの長さで出力するようにすると、512ビットサイズのデータ比較でコンテンツが改ざんされたかどうかをチェックすることができます。
512bitの組み合わせ数は2の512乗通り(10進数で150桁以上)もあります。このため、SHAはパスワード管理にも利用されています。ユーザパスワードをハッシュ化して保存しておくと、正誤の比較も簡単、元のパスワードが何であるかはハッシュ関数とハッシュ値からは計算できないということになります。
ちなみに、なぜSHAに逆関数が存在しないかというと、アルゴリズムの一連の計算の中で、割り算の余りを利用しているからです。割る数と余りがわかっても、割られる数を計算で求めることはできません。
よくあるパスワードハッキングの1つに、ブルートフォースという方法があります。これは、使われそうなパスワードをかたっぱしから試してみるという力業です。たとえば、100万人分のメールアドレスリストをもっていると、ハッカーは数百万回パスワードを簡単に試すことができます。
"mmdd"や"yyyymmdd"のような日付数字、苗字、名前、よく使われるあだ名、辞書にのっている単語、などは類推されやすい定番パスワードです。このようなパスワードは使わないようにしましょう。