Есть ли способ имитировать шифрование пароля порта на python?

Некоторые устаревшие версии Java используют пакет под названием jasypt для шифрования пароля.
Он использует StrongPasswordEncryptor для шифрования паролей.

Похоже, что это можно использовать ниже, на их странице документа
Алгоритм: SHA-256.
Размер соли: 16 байт.
Итерации: 100000.

Там исходный код показывает

 public StrongPasswordEncryptor() {
        super();
        this.digester = new StandardStringDigester();
        this.digester.setAlgorithm("SHA-256");
        this.digester.setIterations(100000);
        this.digester.setSaltSizeBytes(16);
        this.digester.initialize();
    }

Теперь, когда мы больше не используем Java, мы хотели бы продолжать делать то же самое шифрование в python, но не знаем, как портировать эту часть кода.

У меня есть соль и пара текстового пароля и зашифрованного пароля, чтобы проверить, правильно ли работает порт python, просто не знаю, какую библиотеку и какие функции шифровать. Пробовал hashlib.pbkdf2_hmac безуспешно.

Пример обычного текстового пароля: Testing123
Соль: 0DD2E486FAE5B121491CBE78A9B67AF1
Зашифрованный пароль: D1JAI76bwIkEkOIy7IZoLasAFKX0Yy7ujU/M7UBezC7NqxSD3clDyaFB1lz96K98

Вот фрагмент кода Java, который фактически шифрует пароль:

import javax.inject.Inject;
import javax.inject.Named;
import org.jasypt.util.password.StrongPasswordEncryptor;
import com.foobar.users.PasswordEncoder;

public class PasswordEncoderImpl implements PasswordEncoder {

    private String salt;
    private StrongPasswordEncryptor encryptor;

    @Inject
    public PasswordEncoderImpl(@Named("appHash") String appHash) {
        this.salt = appHash;
        encryptor = new StrongPasswordEncryptor();
    }

    @Override
    public String encode(String password) {
        return encryptor.encryptPassword(password + salt);
    }

    @Override
    public boolean verifyPassword(String password, String encryptedPassword){
        return encryptor.checkPassword(password+salt, encryptedPassword);
    }

}

person taesu    schedule 07.11.2018    source источник
comment
Попробуйте и посмотрите, совпадает ли хэш?   -  person SLaks    schedule 07.11.2018
comment
@SLaks не знает, как создать хеш в python. Усталый хеш-лист, чтобы имитировать его с данной информацией, но не повезло. Может быть, мне следует загрузить их банку и пройтись по ней, но это слишком много движущихся частей.   -  person taesu    schedule 07.11.2018
comment
Описание алгоритма находится на странице, на которую вы ссылаетесь, почему вы не можете ее использовать?   -  person Luke Joshua Park    schedule 08.11.2018
comment
@LukeJoshuaPark Я не знаком ни с Java, ни с шифрованием. Располагает ли эта функция дайджеста, как она шифрует строку?   -  person taesu    schedule 08.11.2018
comment
@taesu пароль не шифруется, создается только соленый хэш (дайджест). Чтобы проверить пароль, вам нужно перейти по ссылке, предоставленной Люком, чтобы создать дайджест предоставленного открытого текста пароля и сохраненной соли. Если они совпадут, пароль тоже совпадет. Правильно соль должна быть уникальной для каждого пароля   -  person gusto2    schedule 08.11.2018


Ответы (1)


Хорошо, у меня есть половинчатое решение:

Вот упрощенный код Java, который проверяет, действителен ли данный пароль:

private void start() throws Exception {

    String salt = "0DD2E486FAE5B121491CBE78A9B67AF1";
    String password = "Testing123";
    String previousResult = "QI2KU2VsI/aNr4U3XQ0AdaOk6Qhl4XTaN2ym5cYXxRr8tz/23EvWQHI8sNhRmoP1";

    StrongPasswordEncryptor passwordEncryptor = new StrongPasswordEncryptor();
    String encryptedPass = passwordEncryptor.encryptPassword(password + salt);


    System.out.println(checkPass(salt, password, previousResult));
    System.out.println(passwordEncryptor.checkPassword(password + salt, previousResult));
}

private boolean checkPass(String salt, String password, String previousResult) throws NoSuchAlgorithmException {
    byte[] bytes = previousResult.getBytes(StandardCharsets.US_ASCII);
    byte[] decode = Base64.getDecoder().decode(bytes);

    byte[] secretSalt = new byte[16];
    System.arraycopy(decode, 0, secretSalt, 0, 16);

    byte [] message = (password + salt).getBytes(StandardCharsets.UTF_8);
    byte[] digest = digest(message, secretSalt);

    return Arrays.equals(digest, decode);
}


private byte[] digest(byte [] message, final byte[] salt) throws NoSuchAlgorithmException {

    byte[] digest;

    MessageDigest md = MessageDigest.getInstance("sha-256");
    md.reset();

    md.update(salt);
    md.update(message);


    digest = md.digest();
    for (int i = 0; i < (100000 - 1); i++) {
        md.reset();
        digest = md.digest(digest);
    }

    byte[] secondArray = digest;
    final byte[] result = new byte[salt.length + secondArray.length];

    System.arraycopy(salt, 0, result, 0, salt.length);
    System.arraycopy(secondArray, 0, result, salt.length, secondArray.length);

    return result;
}
person Ilya Gazman    schedule 07.11.2018
comment
Я знаю, но меня больше беспокоит порт StrongPasswordEncryptor jasypt на python, чтобы мы могли продолжать проверять хеш и шифровать пароли таким же образом. - person taesu; 07.11.2018
comment
@taesu о, я вижу. Затем, пожалуйста, предоставьте пример вывода. Я пытаюсь подражать этому - person Ilya Gazman; 07.11.2018
comment
Спасибо за ваше время. Пожалуйста, смотрите вопрос. В коде Java после этого добавляется соль. encryptor.encryptPassword(password + salt); - person taesu; 07.11.2018
comment
@taesu Я не могу получить тот же результат на Java, что и вы. Можете ли вы привести пример того, как получить этот вывод в Java? Куда кладете соль? - person Ilya Gazman; 07.11.2018
comment
добавил код в исходный вопрос. я буквально рву на себе волосы - person taesu; 07.11.2018
comment
@taesu Проверьте мою правку. При запуске вашего примера я всегда получаю разные результаты. Внутри StrongPasswordEncryptor есть случайный - person Ilya Gazman; 08.11.2018
comment
Эй, попробуйте использовать encryptor.checkPassword(password+salt, encryptedPassword); Каждый раз, когда вы шифруете, зашифрованный текст будет другим, но когда вы проверите пароль, он вернет True - person taesu; 08.11.2018
comment
@taesu, Конечно, будет! Но только на этот пробег. Если вы попытаетесь использовать предыдущий результат выполнения, произойдет сбой. Проверьте мой обновленный пример - person Ilya Gazman; 08.11.2018
comment
Нет, D1JAI76bwIkEkOIy7IZoLasAFKX0Yy7ujU/M7UBezC7NqxSD3clDyaFB1lz96K98 также вернет True, так наша унаследованная система Java аутентифицирует пользователей. - person taesu; 08.11.2018
comment
@taesu Да, ты прав! Хорошо, я пытаюсь понять это сейчас - person Ilya Gazman; 08.11.2018
comment
Другим способом было бы использовать банку jasypt и вызывать ее в python для шифрования и проверки пароля, но не уверен, как бы я это сделал, потому что java -jar jasypt-1.9.2.jar возвращает no main manifest attribute, in jasypt-1.9.2.jar - person taesu; 08.11.2018
comment
@taesu, мы можем перевести это на Python. Не волнуйтесь - person Ilya Gazman; 08.11.2018
comment
Это было бы идеально, но не уверен, что это может произойти, может быть, потому, что я не очень хороший разработчик Java. - person taesu; 08.11.2018
comment
@taesu Эй, я прошел половину пути, но мне пора идти. Попробую посмотреть завтра или на выходных. - person Ilya Gazman; 08.11.2018