Как применить шифрование пароля с помощью Spring Security?
Недавно я начал работать над добавлением безопасности в существующее веб-приложение. Приложение использует jcryption для шифрования хешированного пароля перед его отправкой на сервер, а затем на стороне сервера мы выполняем дешифрование, чтобы получить хешированное значение, и затем это хешированное значение сравнивается с полем db password(хешированное значение MD5). Таким образом, мы можем справиться с "Человеком в середине атаки". Настройка работала нормально, пока я не представил уровень Spring Security в приложении (Spring Security 3.2.7 с конфигурацией Java), теперь у меня возникли проблемы с шифрованием, и я действительно не знаю, как действовать дальше.
Все остальное работает, и я использовал Md5PasswordEncoder для хеширования паролей. Проблема в том, что имя пользователя и пароли отправляются в виде простого текста. Я не могу понять, как я могу зашифровать пароль перед отправкой по сети. Как я могу применить AES-шифрование / дешифрование поля имени пользователя / пароля вместе с архитектурой безопасности Spring?
Пожалуйста, поймите, что я уже использую хеширование MD5 в своем приложении, и я хочу слой шифрования над ним. Еще одна вещь, так как это устаревшее приложение, я не могу заставить всех использовать HTTPS, https включен, но это не обязательно для всех. Я больше обеспокоен людьми, которые будут получать доступ к приложению, используя старый добрый http.
2 ответа
Вам нужно использовать HTTPS для отправки паролей ваших пользователей через Интернет.
Серьезно, ваши пользователи могут / будут судиться с вами, если вы этого не сделаете. Недавно LinkedIn отказалась от нескольких миллионов долларов за то, что они не позаботились о паролях своих пользователей.
Сертификаты Startssl бесплатны, а LetsEncrypt бесплатен и скоро начнется.
Выполнять шифрование без HTTPS или хэширования на клиенте неправильно и плохо. Хеш на сервере только.
MD5 - худший из возможных методов хеширования. Снова, вы можете получить иск.
Используйте только следующее: bcrypt, scrypt, PBKDF-2
Spring имеет встроенный кодировщик паролей bcrypt.
Вы можете написать свой собственный PasswordEncoder с пружинной защитой, но сначала вам нужно код шифрования / дешифрования AES, вот пример:
public static String encrypt(String value) {
if(value == null){
return value;
}
// SALT is your secret key
Key key = new SecretKeySpec(SALT.getBytes(), "AES");
try {
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key);
return Base64.encodeBase64String(cipher.doFinal(value.getBytes()));
} catch (Exception exception) {
throw new RuntimeException(exception);
}
}
public static String decrypt(String value) {
if(value == null){
return value;
}
// SALT is your secret key
Key key = new SecretKeySpec(SALT.getBytes(), "AES");
try {
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, key);
return new String(cipher.doFinal(Base64.decodeBase64(value)));
} catch (Exception exception) {
throw new RuntimeException(exception);
}
}
Затем мы можем использовать эти служебные методы с PasswordEncoder, так как вам не нужно расшифровывать пароль пользователя во время аутентификации, это небезопасно, вы должны зашифровать пароль и затем сравнить зашифрованные пароли. (Вы должны сохранить пароли пользователей, закодированные в базе данных). Вот пример:
Открытый класс CustomUserPasswordEncoder реализует PasswordEncoder {
public String encode(CharSequence rawPassword) {
return encrypt(rawPassword.toString());
}
public boolean matches(CharSequence rawPassword, String encodedPassword) {
if (!StringUtils.isBlank(rawPassword) && encode(rawPassword).equals(encodedPassword)) {
return true;
}
return false;
}
}
Теперь мы можем установить кодировщик паролей безопасности Spring следующим образом:
passwordEncoder(new CustomUserPasswordEncoder());