2

getHash(...)以下のコード例では、メソッドのdigest.update(salt)はどのように機能しますか?PHPでロジックを複製する必要があります。このtestHash()メソッドには、いくつかのテスト値が埋め込まれています。コメントアウトすれば試合ができますdigest.update(salt)。PHPで次の組み合わせを試して、運がない(擬似コード)一致を取得しました。

  • sha256($salt.$pass)
  • sha256($pass.$salt)
  • sha256($pass.sha256($salt))
  • sha256($salt.sha256($pass))
  • sha256(sha256($pass).sha256($salt))
  • sha256(sha256($salt).sha256($pass))

コード:

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

public class Owasp {

    private final static int ITERATION_NUMBER = 5;

    public void testhash() throws IOException, NoSuchAlgorithmException, UnsupportedEncodingException {
        byte[] bSalt = base64ToByte("123456");
        byte[] bDigest = getHash(ITERATION_NUMBER, "somepass", bSalt);
        String sDigest = byteToBase64(bDigest);
        System.out.println(sDigest);
    }

    public byte[] getHash(int iterationNb, String password, byte[] salt) throws NoSuchAlgorithmException, UnsupportedEncodingException {
        MessageDigest digest = MessageDigest.getInstance("SHA-256");
        digest.reset();
        digest.update(salt);
        byte[] input = digest.digest(password.getBytes("UTF-8"));
        for (int i = 0; i < iterationNb; i++) {
            digest.reset();
            input = digest.digest(input);
        }
        return input;
    }

    public static byte[] base64ToByte(String data) throws IOException {
        BASE64Decoder decoder = new BASE64Decoder();
        return decoder.decodeBuffer(data);
    }

    public static String byteToBase64(byte[] data) {
        BASE64Encoder endecoder = new BASE64Encoder();
        return endecoder.encode(data);
    }

    public static void main(String[] args) throws NoSuchAlgorithmException, UnsupportedEncodingException, IOException {
        Owasp t = new Owasp();
        t.testhash();
    }
}

編集

使用しているPHPコードを追加しました。テストしたすべてのケースを列挙しないという点で理想的ではありません。-gを使用してコンパイルしたrt.jarファイルを使用してNetbeansでデバッガをステップ実行すると、$salt。$passとして格納されているように見えます。PHPコードを使用すると、一致するものを取得できません。

PHPコード:

<?php
//Without salt
$pass = "somepass";

$hash = hash('sha256', $pass, true);
for($i = 0; $i < 5; $i++) {
    $hash = hash('sha256', $hash, true);
}

echo "Java output without salt: " . "r+G0EnbjURjk99+wMvjnJV51d/tVX8tAn+7VAUCPXRY=" . "\n";
echo "PHP output without salt : " . base64_encode($hash) . "\n";


//With salt
$pass = "somepass";
$salt = "123456";

//I've tried all sorts of combinations and manipulation.
$hash = hash('sha256', $salt.$pass, true);
for($i = 0; $i < 5; $i++) {
    $hash = hash('sha256', $hash, true);
}

echo "Java output with salt: " . "vxZP4vmc+dixEhsZW58+zViLn7XXymirCP7kbl2KtT0=" . "\n";
echo "PHP output with salt : " . base64_encode($hash) . "\n";

アップデート

私はNetbeansのデバッガに何時間も夢中になっていて、digest.update($salt)が呼び出されたときに何が起こっているのかを理解しようとしています。MessageDigestSPIが鍵です。engineUpdate(byte[] input, int offset, int len)と呼ばれていますが、実装が見つかりません。すべてのengineUpdateメソッドが指している可能性がありますがengineUpdate(ByteBuffer input)、確認できません。私は以前にJavaの仕事をしたことがありますが、それは何年も前のことです。hex2bin、packed、unpacked、Base64をすべて試しましたが、運が悪かったです:(すべての投稿を続けます。

4

1 に答える 1

0

アルゴリズムは基本的に、 iterationNbパラメータで指定hash(hash(hash(hash(...hash(password)...)))))された回数です。

ソルトを使用する適切な方法は、ソルトをパスワードと連結してからハッシュすることです。これは、コード内で を実行してdigest.update(salt)から、パスワードを使用してダイジェストを呼び出すことによって行われます。基本的には、次と同じことを行っています。

  String saltedPassword = password + new String(salt, "UTF-8");
  byte[] input = digest.digest(saltedPassword.getBytes("UTF-8"));

もちろん、適切なソルトと同様に、将来的に検証できるように、ハッシュ化されたパスワードと一緒に保存する必要があります。

このウィキペディアのリンクで、パスワード ハッシュを保存するためにソルトがどのように機能するかについての詳細を確認できます。また、パスワードを保存するときにソルトを使用するためのベスト プラクティスについては、この他の StackOverflow の質問を参照してください。

于 2013-01-23T08:36:03.200 に答える