カラクリサイクル

『輝かしい青春』なんて無かった人の雑記

秘密鍵を管理せずに秘密鍵を取り扱う方法

という事柄について、ここの所、ずっと考えていたんだけど、 ようやく一定のアイディアがまとまって来たのでメモります。

なんでそんな矛盾した妙な事を考えていたのか

事の発端としては、

データの同期等を行わずして、秘密鍵やパスワードを扱いたい

というのが、最初に考えていた要件で、 ssh の秘密鍵や PGP (GPG) のマスターキーとか、 あるいは、 Web Services のパスワードとか、そういったモノの類いを、いちいち記録して、 秘密鍵ファイルを秘匿して、と言うのを行いたくなかったねーよ!!1 というのが最初の意思でした。

そして、なんでそう言う credentials の管理を行いたくなかったかって言うと、 例えばマシンを新調した時にssh 秘密鍵をコピーしたりするのはセキュアじゃないし、 あと、最近個人的に導入したが方が良いんじゃね? と考えている GPG のマスターキーとか、 そういう類いを仮に紛失したりすると、後々面倒だよなーって言うのがありました。

それで、色々考えていた結果、

秘密鍵を管理せずに秘密鍵を取り扱う方法について考えるか

と言う、一見矛盾した、と言うより、矛盾でしかないだろソレ、 という命題にブチ当たっていた、と言うのが話の前提です。

で、『秘密鍵を管理せずに秘密鍵を取り扱う』なんて出来るの?

実際にはまだ考えを整理している段階なので、実際に動くコード等は書いていませんが、 これは、たぶん 出来ます

ま、僕は暗号学については素人も同然なので、暗号学的に安全かどうかは判りませんが、 一応、下記の様な考え方で出来るはず……です:

  • 秘密鍵は、それをファイルデータとして用いず 、それを 利用する際にのみ任意の入力から再現 する
  • 秘密鍵は、任意の入力からエントロピーなどを生成 し、 メモリ上にのみ再現する
  • 秘密鍵は、その利用が終えた際に、 メモリ上から破棄 する

そして、具体的な実装、例えば ssh-agent などだったりする場合、その実装は、

  • 上記三つの条件を見たすプログラムに対し、 ssh-agent として振る舞う機構を付ける
  • そして、ssh 接続時には、何らかの形で入力されたパスワードから、秘密鍵をメモリ上に生成する
  • ssh 接続が終了した場合、メモリ上の秘密鍵を速やかに破棄する

という感じになるはず、です。

この方法、本当にセキュアなの?

正直に言うと、 あんまり良く判ってません

と言うのも、例えば、今回の 任意の入力 に対して、 脆弱なパスワードやら入力等 を使っている場合には、割とアッサリ突破されてしまいますし、 また、既存のパスワードを使い回して秘密鍵生成を行なっていた場合でも、 どこからからパスワードが漏れた場合 には、やっぱり突破されてしまいます。

そのため、これをセキュアにする為には、

  1. 既存のサービスで利用しているパスワードは用いない
  2. もしくは、パスワードを使い回す場合には、複数のパスワードを組合せる

の、どちらかの手法しかないんじゃないかなー、なんて思っています。

以上

ま、とりあえず僕の今の考えの内、実際にコードを書くとしたら、

  1. 使い慣れた長いパスワード
  2. 使い慣れた短いパスワード
  3. iPhone 等で使っている PIN コード

を組み合わせ、 salt とか random を生成する場合には、pbkdf2 辺りを用い、さらに、 pbkdf2 の出力結果をまた pbkdf2 に食わせて、みたいな事をするかなーと思っています。

ただこれ、実際にパスワードを生成する度に三つも入力項目がある、と言うのは、 手間的にどうなのかなーとは思いますが。あと、実際にセキュアかどうか、 って言うのは、今一つ判ってないですし。


と言う事で今日の考え事は以上。

ま、気が向いたら、実際にこれを作ってみたいとは思っています。はい。