piyolog

piyokangoの備忘録です。セキュリティの出来事を中心にまとめています。このサイトはGoogle Analyticsを利用しています。

ストレッチングの回数を自動制御することに意味はあるのか考えてみた。

ストレッチングは必要なのか

皆さんは「ストレッチング」という手法をご存知でしょうか。
以前からたびたびTwitter上で「ストレッチングは行う必要があるのか」という議論が交わされています。
最近では太田さんが自身の開発体験を踏まえ、ストレッチングのエントリをされています。
ストレッチング採用の理由−水無月ばけらのえび日記
徳丸本のあれこれを実践してみて気付いたこと−水無月ばけらのえび日記
 
また、北河さんや徳丸さんはストレッチングの必要性に関して次のようなつぶやきをされています。(これだけでは断片的なのでできれば前後の内容も参照してください。)
http://twitter.com/kitagawa_takuji/status/61258646180470784:twitter:detail:left
http://twitter.com/ockeghem/status/75102810236129280:twitter:detail:left
http://twitter.com/ockeghem/status/75103215804354560:twitter:detail:left
  
専門家の方の考えを見ていくと、XSSSQLインジェクションの対策の様に絶対行う必要があるのではなく、状況に応じて(ケースバイケース)という印象を受けました。当たり前かもしれないのですが、必要な場面、そうでない場面があるということです。
では必要性の有無に応じてやり方を変えるということはできないのでしょうか。
現在公開されているストレッチングのサンプルコードの多くは固定回数で行うものとなっており、これを「スマートではない」と揶揄される方も多くいらっしゃいます。なら自動的にその回数を制御したらどうか、というのがこれを書いた経緯です。
 

ストレッチングの回数をどのように自動制御するか

まずそもそも論として、前提となる「ストレッチングの回数をどの程度行う必要があるか」についてです。
詳しい計算根拠は調べていないのですが、先日行われたセミナーではストレッチングに関しての内容もあり、次のようなことがお話しされたそうです。
http://twitter.com/ntsuji/status/84213409012391936:twitter:detail:left
 
これを元に、安直な考えではありますが、次のような計算式を考えました。
( 強固なパスワード文字数 − ユーザーが入力したパスワード文字数 )× ストレッチング指数 = ストレッチング回数
  
たとえば20文字を強固なパスワード文字数、ストレッチング指数を100とした場合の例です。
  ユーザーは8文字のパスワードを設定した場合、ストレッチング回数は1200回になります。
  ユーザーが18文字のパスワードを使用した場合、ストレッチング回数は200回になります。
  ユーザーが20文字以上のパスワードを使用した場合、ストレッチングは行いません。
#念のためですが、この数字や回数はあくまでもここでの例ということにご留意ください。

このように行えば、ユーザー側が設定したパスワードの強度に対して、本当に必要となる回数だけストレッチングを行うことができます。
 
そして「この文字数※をどこに持つのか」という点ですが、ユーザーが入力してきたパスワードの文字数をベースとすればよいだけなので、システム(サーバー側)で持つ必要性はないと考えました。
※ここで述べている文字数とはストレッチングの回数を計算する際に利用する「ユーザーが入力したパスワード文字数」を指しており、「強固なパスワード文字数」はシステム側で持つ必要があります。
 
ざっくりとした流れは次のようなものになります。
ユーザーがパスワードを入力→入力された文字数をカウント→上記式に基づきストレッチング回数を算出→ストレッチング実行→保存しているハッシュ値と比較
 

ソルトでも似たようなことが出来るのではという考え方

ストレッチングの他に、パスワードにはソルトという手法があります。ソルトはハッシュ化する前にパスワードの文字列にユーザーごとにユニークな文字列を付加するものですが、わざわざストレッチング回数を増やすのではなく、このソルト文字数を必要に応じてを1文字その分増やせば済む話ではないかという考え方もあります。
ソルトとストレッチングは私も混合していたのですが、その目的がやや異なっています。ソルトはレインボーテーブルへの対策に用いられますが、ストレッチングはオフラインクラックの時間を稼ぐ目的で用いられます。
ソルトを用いてハッシュ化を行っていても、ソースコードの流出によりソルトを含めたアルゴリズムまで第三者が把握出来た場合、ストレッチングを行っていれば元の文字列が計算されるまでの時間をある程度稼ぐことが出来ます。
そのため、このリスクを低減させるためにはソルトではなくストレッチングが有効となります。そしてこのストレッチングには先のように、必要性の低いケースも考えられることから、その回数を自動制御することに意味があるのではないかと考えます。
また、長い文字列のソルトをまぶす実装できるのであれば、自動制御など余計なことをせずに、(ストレッチングのような計算負荷が高まるといったデメリットもないので)分け隔てなく最初からその最大文字数分のソルトをまぶすのが良いのではとも思います。

ストレッチングの回数を自動制御するメリット・デメリット

というわけでストレッチングの回数を自動制御するメリットデメリットが何かをまとめてみます。

メリット

(1) 強度の高いパスワードには多くのストレッチングをかけずに済む
(2) ソースコードとデータベースのデータが漏えいしても、ストレッチングの回数を把握されずに済む

デメリット

(1)DoS攻撃の原因となる可能性がある
 
尚、今回は単純に文字数だけを見ています。つまり強固なパスワードとして「20文字」が設定されている場合、「aaaaaaaaaaaaaaaaaaaa」も「f@bD4564290ba3_eC22_」も全く同じ強度として解釈され、ストレッチング回数も同数のものが設定されます。これを補うために、記号が1文字以下ならさらにストレッチング回数を+10%する(数字は適当です)などの応用的な処理があってもよいかもしれません。
また、デメリットにあげているDoS攻撃の可能性については、固定回数以上に注意をする必要があります。何でもかんでも回数を多くできるようになってしまうと逆に1文字のパスワードの入力を連続で受けるなどしてシステムへの影響がより大きくなる可能性もあります。そのため、ストレッチング回数の自動制御とはいいつつも、その回数の上限・下限を設定できる(把握できる)必要はあると考えます。