在使用Spring Security时,密码字段在数据库中的长度应该是多少?

huangapple go评论75阅读模式
英文:

What should be password field length in dB when using Spring Security?

问题

我想创建我的用户表,并为用于注册请求的密码字段设置适当的大小。

@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;

}


但在这里,我应该考虑加密密码的长度。我进行了搜索,但没有找到解决方案。因此,在使用Spring Security时,用户表中的密码长度(已加密)是多少,注册用户时密码字段的最大长度是多少?

Spring Security可能会创建适当的数据属性,但即便如此,我还想了解密码字段的算法和长度。

任何帮助将不胜感激。
英文:

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.

答案1

得分: 2

如果您使用Spring Security的建议,使用DelegatingPasswordEncoder1,它将始终使用BCrypt来编码新密码。

而根据这个答案BCrypt哈希密码的总长度始终约为60字节,无论密码有多少字符。哈希密码还需要以{bcrypt}为前缀,它占用8个字节,以便DelegatingPasswordEncoder可以解码它。我们为缓冲区提供了一些额外的字节,因此将其列宽设置为varchar(80)或类似的应该足够了。

对于用户可以使用的密码的最大长度,这取决于您的业务需求。只需根据常识来判断,然后提供足够的缓冲区即可。例如,您认为一个人将其登录密码设置为200个字符是常见的吗?如果您认为这没有意义,那么很可能需要选择一个较小的最大长度值,直到找到对您有意义的最大值,然后再提供一些缓冲区。

英文:

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.

答案2

得分: 1

我不认为你应该真的关心密码的大小,因为你不知道加密算法会为你生成多大的密码。例如,API密钥或加密密码可以非常长(我曾经看到一些加密的API密钥几乎有900个字符)。

在这个现代世界中,计算机、编程语言、数据库和网络都适应了这种情况。此外,出于安全原因,你的密码必须非常强大。

  • 对于Java,使用String类型,它可以支持2,147,483,647个字符。我认为你可以使用120128个字符作为密码大小。
  • 对于你的数据库,比如MySQL(或任何数据库),使用Text类型及其相关子类型。

Spring Security可以创建适当的数据属性,但即使如此,我想知道密码字段的算法和长度。

你可以在Spring Security中定义自定义加密,使用一个bean,在你的配置文件中。以下是Spring Security支持的所有算法的列表NoOpPasswordEncoderStandardPasswordEncoderPbkdf2PasswordEncoderBCryptPasswordEncoderSCryptPasswordEncoder

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

请考虑在管理安全性和应用加密时,有两个方面要考虑:用户输入的密码和存储在数据库中的加密密码。当用户发起身份验证过程时,用户输入的是密码,而不是加密后的密码。验证是在你定义的AuthenticationProvider中进行的。下面是一个示例:

@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);
        // 在这里进行密码比较,比较用户输入的密码和数据库中的加密密码
        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);
    }
}
英文:

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(&quot;Bad credentials&quot;);
        }
        return new UsernamePasswordAuthenticationToken(
            user.getUsername(),
            user.getPassword(),
            user.getAuthorities()
        );
    }

    @Override
    public boolean supports(Class&lt;?&gt; authentication) {
        return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);
    }
}

huangapple
  • 本文由 发表于 2023年3月3日 22:58:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/75628635.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定