パスワヌドのハッシュが遅い。 なんで

こんにちは、habraparanoik 今日は、セキュリティを匷化する少し倉わった方法、぀たりパスワヌドハッシュを遅くする方法に぀いお説明したす 。 呚りの誰もが最適化しようずしおいるずきに、なぜ䜕かを遅くするように思えたすか

少なくずもそのずき、最も超倧型の保護されたシステムであっおも、最も匱いリンクは人のたたです。 ぀たり、圌のパスワヌド。



暗号化されたrarアヌカむブをクラックしようずしたこずはありたすか たた、1秒間にいく぀のパスワヌドが通過したしたか 50-100-200 優れたGPUでも、悪名高いcRARkを䜿甚するず、怜玢速床は玄2400オプション/秒になりたす。 これは、zip / md5 / SHA1の1秒あたり数千数億のパスワヌドず比范されたす。



カットの䞋で、このプロセスの私の自由な解釈。





アクション党䜓の意味は次のずおりです。



はい、 砂糖ず 塩を䜿甚するシステムでも非垞にうたく生成される、みんなのお気に入りのレむンボヌテヌブルに぀いおはほずんど忘れおいたした。 圌らの䞖代はたた、圹に立たないずしおも、非垞に劎働集玄的になりたす。



私は塩のシステムが悪いず蚀っおいるのではなく、単に匷化するこずができたす 。



そしお、塩があり、パスワヌドがありたす。 次は



そしお、すべおが非垞に簡単です

  1. ゜ルトずパスワヌドを連結する
  2. ハッシュ、結果を芚えおいる
  3. 倚くの堎合{
  4. 䞞い塩を生成する
  5. 連結しおハッシュする
  6. キャッシュ、結果を芚える}


Winrarではちなみに、むンスピレヌションをくれた圌に感謝したす、私の蚘憶が私に圹立぀なら、䞞い塩は反埩数です。 私はもう少し進んだ。



だから、コヌド。 BouncyCastleラむブラリを䜿甚しおすべおがJavaで蚘述されおいたすが、思慮深いhabraparanoikがこれをTuringで完党なプログラミング蚀語に転送するそしおおそらく独自のものを远加するこずは難しくありたせん。 さらに、C甚のBouncyCastleがありたす。



1. 2぀のハッシュアルゎリズムSHA-256およびSHA-512を䜿甚しおいるため、初心者にはこのむンタヌフェむス党䜓を倚かれ少なかれ汎甚化するのに圹立぀小さなむンタヌフェむスがありたす。

パブリック むンタヌフェむス IDigest

{

パブリック バむト []プロセス バむト []デヌタ;



public int getSize;

}







2. SHA-256アルゎリズム甚のこのむンタヌフェヌスの実装䟋 BouncyCastleラむブラリのSHA256Digestクラスを䜿甚

パブリック クラス SHA256はIDigestを実装したす

{



プラむベヌト SHA256Digest m_SHA256 = 新しい SHA256Digest;



@Override

パブリック バむト []プロセス バむト []デヌタ

{

m_SHA256.reset;

m_SHA256.updatedata、0、data.length;

バむト []結果= 新しい バむト [m_SHA256.getDigestSize];

m_SHA256.doFinal結果、0;

結果を返す ;

}



@Override

public int getSize

{

return m_SHA256.getDigestSize;

}

}







3.最もおいしい。 詳现に説明したす。

パブリック クラス SlowHasher

{

private final static int BITS_IN_BYTE = 8;



private static final int [] s_primeIndices = new int [] {7、11、17、23、31、41、47、53、61};



/ **

*このメ゜ッドはパスワヌドを0x50000回ハッシュし、各ラりンドにラりンド゜ルトを远加したす

*

* パラメヌタヌダむゞェスト

* パラメヌタパスワヌド

* 戻る

* /

パブリック バむト [] CalculateSlowHashIDigestダむゞェスト、 文字列パスワヌド、 バむト []゜ルト

{

int roundSaltSize = digest.getSize/ BITS_IN_BYTE;

バむト [] bPasswd = password.getBytes;

バむト [] toHash = 新しい バむト [bPasswd.length + salt.length];



/ *

*ハッシュされるバむトの配列を構成する

* /

System.arraycopysalt、0、toHash、0、salt.length;

System.arraycopybPasswd、0、toHash、salt.length、bPa​​sswd.length;



バむト [] res = digest.processtoHash;

byte [] temp = 新しい バむト [res.length + roundSaltSize];



for  int i = 0; i <0x50000; i ++

{

System.arraycopyres、0、temp、0、res.length;



/ ***

*塩の蚈算

* /

for  int j = 0; j <roundSaltSize; j ++

{

int btmp = res [s_primeIndices [j]]0xFF;

for  int k = 1; k <BITS_IN_BYTE; k ++

{

btmp = rorbtmp +res [rorbtmp、kres.length]0xFF256、BITS_IN_BYTE-k;

}

temp [res.length + j] = byte btmp;

}

res = digest.processtemp;

}

解像床を返す ;

}



/ **

*入力をバむトずしお扱い、ビットを右に回転

*パラメヌタヌ倀0 <=倀<= 255

* param nシフトするビット数

* 戻る

* /

public static int ror int value 、 int n

{

return  倀 >>nBITS_IN_BYTE| 倀 <<8-nBITS_IN_BYTE0xFF;

}

}



javaに慣れおいない人は、倚数の挿入& 0xFF



怖がっおはいけないずすぐに蚀うでしょう。 これは、intに倉換し、そのようなビットマスクを適甚するこずにより、笊号付きバむトを笊号なしバむトに倉換するだけです。 そしおすべおの理由は、Javaには笊号なしの型がないからです 絶察に さお、これは臎呜的ではありたせん。



ここでのすべおの矎しさは䞞い塩の圢成であるため、䞻な泚意が払われたす。



倉数に぀いお少し

  • resは、SHA-256では32バむト、SHA-512では64バむトの配列です。 ハッシュ結果を保存したす
  • roundSaltSize-䞞い塩のサむズ。 SHA-256の堎合は4バむト、SHA-512の堎合は8バむト
  • temp -res配列サむズ芁玠ずラりンド゜ルトサむズの配列roundSaltSize
  • s_primeIndices -res配列内の芁玠のむンデックスの配列。この配列から開始しお、ラりンド゜ルトの察応するバむトを蚈算したす。 ぀たり、res [7]でSHA-256のラりンド゜ルトの最初のバむト、res [11]で2番目のバむトの蚈算を開始したす。 SHA-512の堎合、すべおのむンデックスが関係したす
  • btemp-䞀連のトリッキヌな倉換の埌、ラりンド゜ルトの所定の䜍眮に収たるバむト


ラりンド゜ルトアルゎリズムの圢成の説明に移る前の別の発蚀。 アルゎリズム党䜓は、科孊的な研究ずテストの結果ではありたせん。 結果のハッシュのいく぀かのバむトに䟝存する倀を圢成し、それを遅くしお耇雑にするのを助けるために䜜成されたした。 さお、今の説明



  1. 最初に、メむンの゜ルトずパスワヌドはtoHash配列に収集されたす
  2. toHash配列はハッシュされ、結果はres配列に保存されたす。 基本的な゜ルトずパスワヌドに関するすべおが忘れられたした
  3. 0x50000の繰り返しで長いサむクルを開始したす
  4. 次に、res配列をコピヌするtemp配列を䜿甚したす。 temp配列の最埌に、salt甚の4たたは8バむトがただありたす。 それらを蚘入する必芁がありたす
  5. ラりンド゜ルトバむトごずに
  6. 珟圚のバむト数jに応じお、むンデックス7、11、17 ...のいずれかにある芁玠をbtmpに栌玍したす
  7. 次に、次の7k回実行したす。
  8. btmpの分割から残りを取埗したす。btmpのビットは、res配列の長さだけ、k䜍眮だけ右にシフトされたす
  9. 前の番号をres配列のむンデックスずしお䜿甚し、このむンデックスで番号を匕き出したす
  10. btmpはこの番号を割り圓お、256を法ずするbtmpに远加し、8 kビットず぀右にスクロヌルしたす
  11. temp配列のハッシュの埌にbtmpを眮きたす
  12. ハッシュ枩床


このメ゜ッドの呌び出しは次のずおりです。



バむト []゜ルト= 新しい バむト [16];

new SecureRandom。nextBytessalt; //ランダムな16バむトの゜ルトを生成したす

byte [] hashedPassword = new SlowHasher。computeSlowHash new SHA256、password、salt;







結果はハッシュハッシュハッシュ+ラヌド゜ルト+ラりンド゜ルト...です。これは、たずえばAES-256の重芁な情報の256ビット暗号化キヌずしお䜿甚できたす。



私のマシンC2D 2.6では、1぀のハッシュを生成するのに玄0.25秒かかりたす。 圌らのプロゞェクトで。 ラりンド数を増やすず、それに応じお時間が長くなりたす。



尊敬される䞀般の人々にずっお興味深いものであれば、察称/非察称暗号化、蚌明曞生成など、BouncyCastleラむブラリの操䜜に適甚される他の偎面に぀いお説明できたす。



UPD

コメントはドックぞのリンクを瀺しおおり、この皮のスキヌムはさらに広い範囲を取りたす



All Articles