PHP和Java在bcrypt加密算法实现上的差异

2022/4/26 14:12:41

本文主要是介绍PHP和Java在bcrypt加密算法实现上的差异,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

背景:

PHP的bcrypt默认采用的是CRYPT_BLOWFISH加密算法,使用的salt是$2y$,而Java使用的salt是$2a$,当使用Java对由PHP的bcrypt加密的密文进行校验时,会因为salt的这个差异导致Java出现下面的错误:

Encoded password does not look like BCrypt

从官方文档对CRYPT_BLOWFISH的说明里,可以证实:

  • CRYPT_BLOWFISH - Blowfish hashing with a salt as follows: "$2a$", "$2x$" or "$2y$", a two digit cost parameter, "$", and 22 characters from the alphabet "./0-9A-Za-z". Using characters outside of this range in the salt will cause crypt() to return a zero-length string. The two digit cost parameter is the base-2 logarithm of the iteration count for the underlying Blowfish-based hashing algorithm and must be in range 04-31, values outside this range will cause crypt() to fail. "$2x$" hashes are potentially weak; "$2a$" hashes are compatible and mitigate this weakness. For new hashes, "$2y$" should be used. Please refer to » this document for full details of the related security fix.

解决办法,分为两种:

第一种,也是最简单的,在密文校验前,先将密文的$2y$替换为$2a$

第二种,重写spring boot的BCryptPasswordEncoder.java,之所以会出现上述错误,主要是下面这个方法:

    public boolean matches(CharSequence rawPassword, String encodedPassword) {
        if (encodedPassword == null || encodedPassword.length() == 0) {
            logger.warn("Empty encoded password");
            return false;
        }

        if (!BCRYPT_PATTERN.matcher(encodedPassword).matches()) {
            logger.warn("Encoded password does not look like BCrypt");
            return false;
        }

        return BCrypt.checkpw(rawPassword.toString(), encodedPassword);
    }

 

 

参考资料:

https://www.php.net/manual/en/function.crypt.php



这篇关于PHP和Java在bcrypt加密算法实现上的差异的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程