복붙노트

[SPRING] 스프링 보안에서 새로운 PasswordEncoder를 사용하는 방법

SPRING

스프링 보안에서 새로운 PasswordEncoder를 사용하는 방법

Spring Security 3.1.4.RELEASE에서, 오래된 org.springframework.security.authentication.encoding.PasswordEncoder는 org.springframework.security.crypto.password.PasswordEncoder를 위해 더 이상 사용되지 않습니다. 내 응용 프로그램이 일반에게 공개되지 않았기 때문에, 새로운 API로 이전하기로 결정했습니다.

지금까지 ReflectionSaltSource를 사용하여 암호로 사용자의 소금을 자동으로 사용했습니다.

String encodedPassword = passwordEncoder.encodePassword(rawPassword, saltSource.getSalt(user));

로그인 과정에서, Spring은 또한 사용자가 로그인 할 수 있는지 또는 로그인 할 수 없는지를 확인하기 위해 bean을 사용했다. SHA-1의 기본 구현 인 StandardPasswordEncoder는 새로운 패스워드 인코더에서 이것을 달성 할 수 없다. 인코더 생성 중 글로벌 비밀 소금.

비 권장 API로 설정하는 방법에 대한 합리적인 방법이 있습니까?

해결법

  1. ==============================

    1.실제로 사용자를 기존 형식으로 등록하지 않은 경우 BCrypt 암호 엔코더 대신 사용하는 것이 가장 좋습니다.

    실제로 사용자를 기존 형식으로 등록하지 않은 경우 BCrypt 암호 엔코더 대신 사용하는 것이 가장 좋습니다.

    소금에 대해 전혀 염려 할 필요가 없으므로 번거롭게 할 필요가 없습니다. 세부 사항은 인코더 내부에 완전히 캡슐화됩니다. BCrypt를 사용하는 것은 일반 해시 알고리즘을 사용하는 것보다 강력하며 다른 언어를 사용하는 응용 프로그램과 호환되는 표준이기도합니다.

    새로운 애플리케이션을위한 다른 옵션을 선택할 이유가 없습니다.

  2. ==============================

    2.저를 위해 일하는 BCrypt의 구현은 다음과 같습니다.

    저를 위해 일하는 BCrypt의 구현은 다음과 같습니다.

    spring-security.xml

    <authentication-manager >
        <authentication-provider ref="authProvider"></authentication-provider>  
        </authentication-manager>
    <beans:bean id="authProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
      <beans:property name="userDetailsService" ref="userDetailsServiceImpl" />
      <beans:property name="passwordEncoder" ref="encoder" />
    </beans:bean>
    <!-- For hashing and salting user passwords -->
        <beans:bean id="encoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>
    

    자바 클래스에서

    PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
    String hashedPassword = passwordEncoder.encode(yourpassword);
    

    봄 보안에 대한 자세한 예를 보려면 여기를 클릭하십시오.

    희망이 도움이 될 것입니다.

    감사

  3. ==============================

    3.나는 비슷한 문제가 있었다. 사용자가 암호를 변경하거나 다시 등록하기를 원치 않으므로 레거시 암호화 된 암호 (Base64 / SHA-1 / Random salt Encoded)를 유지해야했습니다. 그러나 앞으로 나아가는 BCrypt 엔코더도 사용하고 싶었습니다.

    나는 비슷한 문제가 있었다. 사용자가 암호를 변경하거나 다시 등록하기를 원치 않으므로 레거시 암호화 된 암호 (Base64 / SHA-1 / Random salt Encoded)를 유지해야했습니다. 그러나 앞으로 나아가는 BCrypt 엔코더도 사용하고 싶었습니다.

    내 솔루션은 일치하기 전에 먼저 사용 된 암호화 방법을 확인하는 맞춤형 디코더를 작성하는 것이 었습니다 (BCrypted는 $로 시작).

    소금 문제를 해결하기 위해 수정 된 사용자 객체를 통해 소금 + 암호화 된 암호의 연결 문자열을 디코더에 전달합니다.

    디코더

    @Component
    public class LegacyEncoder implements PasswordEncoder {
    
        private static final String BCRYP_TYPE = "$";
        private static final PasswordEncoder BCRYPT = new BCryptPasswordEncoder();
    
        @Override
        public String encode(CharSequence rawPassword) {
    
        return BCRYPT.encode(rawPassword);
        }
    
        @Override
        public boolean matches(CharSequence rawPassword, String encodedPassword) {
    
        if (encodedPassword.startsWith(BCRYP_TYPE)) {
            return BCRYPT.matches(rawPassword, encodedPassword);
        }
    
        return sha1SaltMatch(rawPassword, encodedPassword);
        }
    
        @SneakyThrows
        private boolean sha1SaltMatch(CharSequence rawPassword, String encodedPassword) {
    
        String[] saltHash = encodedPassword.split(User.SPLIT_CHAR);
    
        // Legacy code from old system   
        byte[] b64salt = Base64.getDecoder().decode(saltHash[0].getBytes());
        byte[] validHash = Base64.getDecoder().decode(saltHash[1]);
        byte[] checkHash = Utility.getHash(5, rawPassword.toString(), b64salt);
    
        return Arrays.equals(checkHash, validHash);
        }
    
    }
    

    사용자 객체

    public class User implements UserDetails {
    
        public static final String SPLIT_CHAR = ":";
    
        @Id
        @Column(name = "user_id", nullable = false)
        private Integer userId;
    
        @Column(nullable = false, length = 60)
        private String password;
    
        @Column(nullable = true, length = 32)
        private String salt;
    

    . .

        @PostLoad
        private void init() {
    
        username = emailAddress; //To comply with UserDetails
        password = salt == null ? password : salt + SPLIT_CHAR + password;
        }        
    

    또한 새 BCrypt 형식으로 암호를 다시 인코딩하고이를 바꿀 수있는 후크를 추가 할 수 있습니다. 따라서 이전 방법을 단계적으로 제거하십시오.

  4. ==============================

    4.방금 인터넷을 돌아 봄으로써 이것과 Spring의 옵션을 읽어 보았습니다. 두 번째 루크의 대답은 BCrypt (스프링 소스 코드에서 언급했습니다)를 사용하십시오.

    방금 인터넷을 돌아 봄으로써 이것과 Spring의 옵션을 읽어 보았습니다. 두 번째 루크의 대답은 BCrypt (스프링 소스 코드에서 언급했습니다)를 사용하십시오.

    내가 왜 해시 / 소금을 사용해야하는지 BCrypt를 사용하는 것이 좋은 선택 인 이유를 설명하는 가장 좋은 자료는 다음과 같습니다. Salted Password Hashing - Righting.

  5. from https://stackoverflow.com/questions/17444258/how-to-use-new-passwordencoder-from-spring-security by cc-by-sa and MIT license