用户密码加密编码使用 Bcrypt 代替 MD5,SHA1和SHA256

您所在的位置:网站首页 md5和sha256区别 用户密码加密编码使用 Bcrypt 代替 MD5,SHA1和SHA256

用户密码加密编码使用 Bcrypt 代替 MD5,SHA1和SHA256

2024-03-09 00:51| 来源: 网络整理| 查看: 265

先入为主阐述一下Bcrypt编码算法两个优点

相同的原文每次编码出来的密文不相同编码的速度很慢

是的这就是Bcrypt的优点,有经验的读者看上去会觉得奇怪,这还算得上是“优点”吗!特别是像编码的速度慢这一点。在这里为了说明这是所谓的“优点”不得不先从用户密码存储安全方面说起: 首先提及MD5编码算法大家马上就会联想到这是一种可以破解的加密算法,破解的方法主要是采用“彩虹表“(不清楚可在网上搜索),上述攻击方法最根本就是相同的原文经过MD5编码之后产生相同的密文,(简单说就是相同密码得出相同的密文,那么反过来就可以推导出原文),有经验的开发者会采用salt和多重MD5编码的方式来避免密文被破解,如果攻击者预先知道或者能够获取到足够多的信息上述两种方式也是很容易被攻破的,说到这里不喻而明Bcrypt第一个优点就是为了解决这种问题。当然MD5是一个相对过时的哈希编码算法,当前就算简单起见也应当选择SHA256等相对安全性更高的哈希编码算法。那第二点为何编码的速度很慢有什么帮助,你想想通过彩虹表攻击之前必需预先准备一套容量足够大的表碰撞表,如果能过MD5算法和Bcrypt作对比,因为Bcrypt足够慢而致依生成碰撞表付出更大量的计算量,这种困难可以使得生成碰撞表变得不现实,所以破解的难度就相应增大,正因为上述的原因所以说Bcrypt更适合作为用户密码加密编码的算法来使用,并且在使用的过程中不涉及多重编码,Salt和Pepper等问题,所以使用它的API使得代码更简洁和易懂。 以下是Bcrypt编码算法的实现,该类是引用自Spring Security模块中的 org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder

/** * Implementation of PasswordEncoder that uses the BCrypt strong hashing function. Clients * can optionally supply a "strength" (a.k.a. log rounds in BCrypt) and a SecureRandom * instance. The larger the strength parameter the more work will have to be done * (exponentially) to hash the passwords. The default value is 10. * * @author Dave Syer * */ public class BCryptPasswordEncoder implements PasswordEncoder { private Pattern BCRYPT_PATTERN = Pattern .compile("\\A\\$2a?\\$\\d\\d\\$[./0-9A-Za-z]{53}"); private final Log logger = LogFactory.getLog(getClass()); private final int strength; private final SecureRandom random; public BCryptPasswordEncoder() { this(-1); } /** * @param strength the log rounds to use, between 4 and 31 */ public BCryptPasswordEncoder(int strength) { this(strength, null); } /** * @param strength the log rounds to use, between 4 and 31 * @param random the secure random instance to use * */ public BCryptPasswordEncoder(int strength, SecureRandom random) { if (strength != -1 && (strength BCrypt.MAX_LOG_ROUNDS)) { throw new IllegalArgumentException("Bad strength"); } this.strength = strength; this.random = random; } public String encode(CharSequence rawPassword) { String salt; if (strength > 0) { if (random != null) { salt = BCrypt.gensalt(strength, random); } else { salt = BCrypt.gensalt(strength); } } else { salt = BCrypt.gensalt(); } return BCrypt.hashpw(rawPassword.toString(), salt); } 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); } }

测试的代码如下:

@Test public void testBCryptPasswordEncoder() { BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder(6); for (int i = 0; i


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3