Как сравнить соль с сгенерированным паролем? - PullRequest
1 голос
/ 29 марта 2020

Итак, я пытаюсь сравнить свой оригинальный пароль с посоленным паролем. Я знаю, как сравнить пароль ha sh, я беру оригинальный пароль, добавляю ha sh, и он работает. Однако я не знаю, как сравнить соль.

public static String saltPassword(String password) throws NoSuchAlgorithmException{
     String salt = getSalt();
     return password + salt;
 }
public static String getSalt(){
     Random r = new SecureRandom();
     byte[] saltBytes = new byte[32];
     r.nextBytes(saltBytes);
     return Base64.getEncoder().encodeToString(saltBytes);
 }

Что мне нужно сделать, чтобы сравнить исходный пароль с этим?

Это буквально то, что мое назначение говорит: «Сравните сгенерированный пароль с сохраненным солью и хешированным паролем». .

Ответы [ 3 ]

2 голосов
/ 29 марта 2020

Вы должны также хранить соль. Соль используется для enet генерации одного и того же хешированного пароля, когда два пользователя выбирают один и тот же пароль. что-то вроде следующих кодов может быть использовано для сохранения пароля как hashedPassord и проверки введенного пароля. Он не завершен, но может использоваться в качестве примера кода.

private static void savePassword(String rawPassword) throws InvalidKeySpecException, NoSuchAlgorithmException {
    byte[] salt = getSalt();
    String hashedPassword = getHashedPassword(rawPassword, salt);
    String encodedSalt = base64Encode(salt);

    /* todo: store hashPassword and encodedSalt */
}

private static boolean verifyPassword(String rawPassword, String hashedPassword, String encodedSalt) throws InvalidKeySpecException, NoSuchAlgorithmException {
    return Objects.equals(hashedPassword, getHashedPassword(rawPassword, base64Decode(encodedSalt)));
}

private static String getHashedPassword(String rawPassword, byte[] salt) throws NoSuchAlgorithmException, InvalidKeySpecException {
    KeySpec spec = new PBEKeySpec(rawPassword.toCharArray(), salt, 65536, 128);
    SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
    byte[] hash = factory.generateSecret(spec).getEncoded();
    return base64Encode(hash);
}

private static byte[] getSalt() {
    Random r = new SecureRandom();
    byte[] saltBytes = new byte[32];
    r.nextBytes(saltBytes);
    return saltBytes;
}

private static String base64Encode(byte[] src) {
    return Base64.getEncoder().encodeToString(src);
}

private static byte[] base64Decode(String src) {
    return Base64.getDecoder().decode(src);
}
0 голосов
/ 29 марта 2020

Хорошо, вот что у меня есть. Я хотел бы найти сохраненный пароль, но мой учитель не делает этого так в своем решении видео

public static String saltPassword(String password) throws NoSuchAlgorithmException{
     String salt = getSalt();
     return hashPassword(password + salt);
 }
 public static String getSalt(){
     Random r = new SecureRandom();
     byte[] saltBytes = new byte[32];
     r.nextBytes(saltBytes);
     return Base64.getEncoder().encodeToString(saltBytes);
 }
 public static String generatePassword(){
        String charSet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_-+!@#$%";
        String password = "";
        int start = 0;
        int stop = 0;
        int minLength = 8;

        for (int i = 0; i <= minLength; i++) {
                // get a random character from the chars string
                start = getRandomNumber(charSet.length());
                stop = start + 1;
                password += charSet.substring(start, stop);
        }        
        return password;
    }
    private static int getRandomNumber(int maxValue){
        double randomNumber;
        randomNumber = Math.floor(Math.random() * maxValue);

        return (int)randomNumber;
    }
    public static String hashPassword(String password)throws NoSuchAlgorithmException{
        MessageDigest md = MessageDigest.getInstance("SHA-256");
        md.update(password.getBytes());
        byte[] mdArray = md.digest();
        StringBuilder sb = new StringBuilder(mdArray.length * 2);
        for (byte b : mdArray){
            int v = b & 0xff;
            if(v < 16){
                sb.append('0');
            }
            sb.append(Integer.toHexString(v));
        }
        return sb.toString();   
    }

Затем, чтобы создать его, я собираюсь go

    String newPassword = PasswordUtil.generatePassword();
    String hashedPassword = "";
    String saltedPassword = "";

try{
            hashedPassword = PasswordUtil.hashPassword(newPassword);
        }
        catch(NoSuchAlgorithmException e){
            System.out.println();
        }
        try{
            saltedPassword = PasswordUtil.saltPassword(hashedPassword);
        }
        catch(NoSuchAlgorithmException e) {
            System.out.println();
        }

Что будет дальше?

это хешированный пароль:

50f99d2a635cc9bac7e001506789b55a7c603d93c89d362cc5d95ab257fc2666

и это ха sh с солью

e954fbc2309cc359cd603effb6d0644947a3253110ad6c3b2416dd49168331a3
0 голосов
/ 29 марта 2020

Как мне сравнить соль с сгенерированным паролем?

Что мне нужно сделать, чтобы сравнить исходный пароль с этим?

Ответ заключается в том, что вы не делайте также, если эти вещи.

Чтобы зарегистрировать оригинальный пароль, вы делаете следующее:

  1. Получите соль 1
  2. Объедините оригинальный пароль с солью
  3. Ха sh, что.
  4. Сохраните соль и га sh.

Затем вы сбрасываете оригинальный пароль ,

Чтобы проверить, что предоставленный пароль, вы делаете следующее:

  1. Поиск сохраненного ха sh и соответствующей соли, которые были созданы при регистрации; см. выше.
  2. Объедините прилагаемый пароль и соль так же, как указано выше.
  3. Ха sh это как указано выше.
  4. Сравните полученный ха sh с сохраненным ха sh. Если они совпадают, то предоставленный пароль является правильным паролем.

Как видите, вы не сравниваете ни соль, ни исходный пароль ни с чем.

Но также важно, чтобы вы использовали ту же соль при создании хэшей для оригинального пароля и пароля, который вы проверяете. Если вы этого не сделаете, проверка пароля не работает.


1 - соль - это просто число или строка. В идеале значения соли должны быть разными. Соль заключается в том, чтобы избежать так называемой атаки «радужной таблицы» для восстановления исходного пароля из украденного (несоленного) пароля ha sh. Если существует, скажем, миллион возможных значений соли, то злодеи должны создать миллион различных радужных таблиц. Создание и хранение многих радужных таблиц становится непрактичным.

...