へっぽこびんぼう野郎のnewbie日記

けろけーろ(´・ω・`)! #vZkt8fc6J

さくらのレンタルサーバにSSHプロトコルで接続してみて、やっと公開鍵認証の意味がわかって頭がハゲそう。

はじめに

公開鍵認証ってなに?便利なの?それ食えるの?って人を対象にしてるよ。
公開鍵認証は別にどこでも使えるんだけど、主にクライアントとサーバとのやり取りを安全にするために使われているよ。
HTTPS通信という安全に通信できるプロトコロルもある。
ただこれはまあこんな感じなんだろうなとおぼろげに理解はしているけど、人に説明できるようなレベルで理解してないから割愛するよ。

公開鍵認証って何?めんどくさいし難しそうだからパスワード認証でいいよ

難しいのはたぶん、難しく書いてる人が多いからです。

公開鍵認証がオススメされる理由は大きくわけて2つあります。

1、パスワード認証より遥かに安全

2、ログイン時にいちいちパスワードを入力しなくてもよいふうにもできる

2番目についてたまに『セキュリティこわいからうんたら』と言っている人がいるようですが、そこまで怖くないです。
確かにパスフレーズつけた方が安全ですが、
ログイン時にパスフレーズつけるの、めんどくさくない?というのと
そんなもんは、RSA暗号に比べたら屁のようなものだということと
ていうかおまえ、Macのキーチェーンで保存してるくせに何言ってるんだもあります。

GitHubの人も言ってる。

Working with SSH key passphrases - User Documentation

こっちは日本語。


SSH秘密鍵のパスフレーズは(つけるなら)11文字以上にしましょうねという話 - 本当は怖い情報科学

追記(2015/02/12):
 あとでGitHubSSH認証について調べたところ、やはりこの辺は自信ないです。
 主張は相変わらずかわりませんが、パスフレーズはつけた方が良さげかもしれません。
 あと、この手順さえ知ってしまえば他のサービスでのSSH認証についての理解がかなり深まり楽になると思います。

なんで安全なんだ!!!

公開鍵認証というのは、素数を使った認証方法です。
ざっくり言うと、素因数分解の難しさを使った認証方式らしいです。
計算しないと???のままだと思います。
証明はできないので、ちょっと勘弁してください。

ここがよさそう。
RSA暗号の世界 | サルにも分かるRSA暗号

その後こっちを読むとわかりやすいです。

What is RSA algorithm (Rivest-Shamir-Adleman)? - Definition from WhatIs.com

さいきんはデフォルトで2048bit(2の2048乗・約3.2317006071311007300714876688669951960444102669 × 10^616)
までの数の中からある素数素数のかけ算から求められたものを使うので、安全というわけですね。

それに比べたら、公開鍵認証を使わないパスワード認証は、英数字10桁とか長くても12桁とかなので、(62^10 = 8.39299365868340224 × 10^17)という、
RSA暗号に比べたら屁みたいなものです。
単純計算でセキュリティが、約10^600倍も向上するのでぜひやりましょう。

10^600という数は参考までに、

いつも1枚しか買ってないのに10回ジャンボ宝くじの1等を当てた上で、50回くらい隕石にぶつかりつつ交通事故に10回くらい自分が遭い、さらに駄菓子屋でお菓子を1個買ったらあたりが出るくらいの確率が1/10^600です。

認証の注意点

まちがえてはいけないのは、
秘密鍵は、id_rsaというファイルです。公開鍵はid_rsa.pubというファイルです。pubはpublicですね。

それから、一度認証してみたあと、なんかうまくいかなかったからと言った理由から
つなぐ側(クライアント側)で、.sshディレクトリを削除し始めるのは絶対にやめましょう。
バックアップぜったい。
しにます。

デスマーチの仕返しだ!
とか言って時限爆弾的に文字を1個置換するシェルスクリプト組むのだけはやめてあげてください。

鍵をつくる

秘密鍵と公開鍵をつくります。
SSH login without password
このサイトがすばらしいです。楽。

-tというオプションは、typeという意味で、-t rsaRSA暗号を作りますよという意味です。
DSA方式もあるらしいですが、よくわからんしRSA暗号で作ります。
上に書いた『仕組み』のやつがRSAです。

このコマンドは、公開鍵と秘密鍵の両方を作ります。

また、理由は次に書きますが、このコマンドはサーバ側ではなく、クライアント側で打ちます。

$ ssh-keygen -t rsa

『なんでクライアント側で打つんだ!サーバ側でもいいだろ!』

秘密鍵は、クライアント側に置かなければなりません。
バレてはいけないやつです。
したがって、間違ってもこれをメールで送ってはいけません。
LINEならおっけーとかいうとんちを利かせるのももちろんダメです。
そもそも秘密鍵は外部に見せる類のものではなく、特に理由もなく作ったあと触れるものでもありません。

これはどこかから公開鍵で暗号化されて送られてきた物を復号するときにも使いますし、
本当にこれは僕が送ったよーという証明するときにも使います。

『なんでそんなことわかるの?』というのは、秘密鍵はその人しか知らないからということからわかります。
(そういう前提で作られた暗号です)

「ケースケしか知らないことを知っているんだからそれはケースケだろ」的な発想です。
そう考えると、公開鍵で暗号化されたのが自分だけ読めるのも、僕が送ったよと証明できるのも納得できそうです。

「僕しか使えないもん使って何かしらやったんだから、僕ってわかるだろ!」というノリです。

つまり
秘密鍵は、絶対に、絶対に、絶対に、誰かに教えてはいけないし、どこか別の場所に保存しておくとかいった必要がないのです。

だからすごい暗号なんだよ!!!!!!!!!!!!あたまいいね!!!!

逆に公開鍵はどんどん教えてしまってかまいません。
そこらへんのギャングやテロリストたちに教えても痛くも痒くもありません。



話を戻しまして、
クライアント側で打たなければいけない理由は、逆に考えるとわかります。

もしサーバ側で公開鍵と秘密鍵を作ったら、クライアント側に秘密鍵を送らなければいけません。
それはなぜか?
クライアント側に公開鍵を送ったとしても、ギャングと区別つかなくなるからです。
だってこの公開鍵ギャングにも配るし。

だから秘密鍵をクライアント側に送ることにしy……

でもちょっとまって。
秘密鍵って秘密にしなきゃいけないんじゃないの?
盗聴される恐れがあるんじゃないの?

こういう心配がありますね。
『そんなの一瞬だから大丈夫だよwww別に気にするなよwww』と思うかもしれません。
一理あります。

でも、暗号というのはそもそも政府とか国防とかのために使われているわけです。
別に民間人のくだらない情報のための鍵ならどうでもいいですが、
大事な大事な大事な鍵の場合は、そういう隙が仇になります。たぶん。知らん。

『まあ大体手間は同じなんだから、クライアント側で作った方がいいよね』という発想で、
クライアント側で作るようにしたほうがいいと思います。

というか、むしろサーバ側で作ると秘密鍵送るときめんどくさい(実体験済み)

だからまあ、要するに、別にサーバ側で作ってもいいですけど、クライアント側で作った方がやっぱりいいです。

authorized_keysについて

これは要は、単にファイル名変えただけで、サーバ側が『ユースケの公開鍵』を持っているだけです。
別に名前を変えたくなければ設定しとけばいいです。

これのおかげで
他の秘密鍵がいくらきても、『いやお前ユースケじゃないじゃん』と、他からのアクセスを弾いてくれるわけですね。

クライアント側が『僕はユースケ!』という秘密鍵を持っていないとアクセスできない。
そういう仕組みです。

おわりに

RSAはとてもすごいというお話でした。