0

I want to create my User table and set a proper size for password field used for signup request.

@Entity
@EqualsAndHashCode(callSuper = true)
public class User extends Person {

    @Column(length = 50, nullable = false, unique = true)
    private String username;

    @Column(length = 120, nullable = false)
    private String password;
}

But in here, I should think the length of the encrypted password. I made a search but could not found a solution. So, when using Spring Security, what is the password length in the User table (encrypted) and max length for password field while registering user?

Spring Security may create proper data properties, but even so, I want to know the algorithm and the length for password field.

Any help would be appreciated.

2 Answers2

2

If you use spring security 's suggestion which use DelegatingPasswordEncoder , it will always use BCrypt to encode a new password.

And from this answer , the total length of a BCrypt hashed password is always about 60 bytes no matter how many characters does the password has. The hashed password also needed to be prefixed with {bcrypt} which is 8 bytes in order for DelegatingPasswordEncoder can decode it. We give it some extra bytes for buffer and so make its column to be varchar(80) or so should be more than enough.

For the maximum length of the password that an user can use ,it depends on your business requirement. Just judge it by common sense and give it enough buffer should be okay. For example, do you think it is common for a person to set his login password to be 200 characters ? If you think it does not make sense , most probably you need to choose the maximum length to a smaller value until you find a maximum value that make sense to you and then give it some buffer.

Ken Chan
  • 84,777
  • 26
  • 143
  • 172
  • 1
    as i mentioned in the answer , and based on the information that i get , the exact length of the bcrypt hased password in the worst case is 60 + 8 = 68 bytes. But i will not define exactly its column to be varchar(68). i like to give some buffer to it simply because it make me feel more safe – Ken Chan Mar 03 '23 at 18:57
  • 1
    no matter how long the raw password are , the hashed password will always be 59 bytes or 60 bytes. – Ken Chan Mar 03 '23 at 19:04
  • 1
    80 or 120 really does not have much differences , really doesn't matter.. Both are okay to me. just follow your heart and moving forward to to next more meaningful things. – Ken Chan Mar 03 '23 at 19:38
1

I don't think you should really care about the size of the password because you don't know how the encryption algorithm will generate the password for you. API Keys for instance or crypted password can be very length (I have seen for instance some encrypted API key that have almost 900 chars).

The computers, the languages, the databases and the network in this modern world are adapted for this kind of situation. Also, for security issue, your password have to be very strong.

  • For Java, use String it can support 2,147,483,647 characters. IMO you can use 120 or 128 chars for the password size.
  • For your database, MySQL for example (or any database) use Text types and its associated sub types.

Spring Security may create proper data properties, but even so, I want to know the algorithm and the length for password field.

You can define a custom encryption in Spring Security with a bean, in you configuration file. The following is the list of all the algorithms supported by Spring Security: NoOpPasswordEncoder, StandardPasswordEncoder, Pbkdf2PasswordEncoder, BCryptPasswordEncoder, SCryptPasswordEncoder

@Bean
public PasswordEncoder bCryptPasswordEncoder() {
    return new BCryptPasswordEncoder();
}

Take in consideration that you have 2 sides when managing your security and applying encryption: the user side password and the encrypted password stored in the database. When the user issue an authentication process, the user type his password, not the encrypted password. The verification is made in a AuthenticationProvider that you define. See an example bellow:

@Service
public class UserAuthenticationService implements AuthenticationProvider {

    private UserDetailsService service;
    private PasswordEncoder encoder;

    public UserAuthenticationService(UserDetailsService service, PasswordEncoder encoder) {
        this.service = service;
        this.encoder = encoder;
    }

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        var username = authentication.getName();
        var password = authentication.getCredentials().toString();
        var user = service.loadUserByUsername(username);
        // You make this comparison here, between both password the user and the encrypted one in the database
        if (!encoder.matches(password, user.getPassword())) {
            throw new BadCredentialsException("Bad credentials");
        }
        return new UsernamePasswordAuthenticationToken(
            user.getUsername(),
            user.getPassword(),
            user.getAuthorities()
        );
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);
    }
}
Harry Coder
  • 2,429
  • 2
  • 28
  • 32