【日常经验】五种密码加密方式比较
背景 :日常需要加密的场景有很多,市场上的加密方式也很多,我们该如何选择呢,下面进行详细梳理汇总,供大家参考选择。
1 、密码加密介绍
加密类型目前主流的有三种:对称加密、非对称加密和摘要加密
(1)对称加密: 文件加密和解密使用相同的密钥,即加密密钥也可以用作解密密钥
比如3DES、AES等算法,使用这种方式加密是可以通过解密来还原出原始密码的,当然前提条件是需要获取到密钥。不过既然大量的用户信息已经泄露了,密钥很可能也会泄露,当然可以将一般数据和密钥分开存储、分开管理,但要完全保护好密钥也是一件非常复杂的事情,所以这种方式并不是很好的方式。
优点:加密速度快,效率高
缺点:相对不太安全(不要保存敏感信息)
(2)非对称加密:两个密钥:公开密钥(publickey)和私有密钥,公有密钥加密,私有密钥解密
优点:与对称加密相比,安全性更高
缺点:加密和解密速度慢,建议少量数据加密
(3)摘要加密(单向加密):对数据进行哈希运算来生成一个固定长度的摘要(也称为哈希值或消息摘要)
使用这些算法后,无法通过计算还原出原始密码,而且实现比较简单,因此很多互联网公司都采用这种方式保存用户密码,曾经这种方式也是比较安全的方式,但随着彩虹表技术的兴起,可以建立彩虹表进行查表破解,目前这种方式已经很不安全了。
其实之前公司也是采用的这种MD5加密方式。
特点:不可逆,唯一性
场景:密码加密、数字签名
常见的加密算法:MD5、BCrypt
(4):PBKDF2算法
PBKDF2(Password-Based Key Derivation Function 2)算法不属于传统意义上的加密方式,而是一种密钥派生算法。它主要用于从密码导出加密密钥,通过多次迭代哈希运算和使用随机盐值来增加密码的强度和安全性。
该算法原理大致相当于在HASH算法基础上增加随机盐,并进行多次HASH运算,随机盐使得彩虹表的建表难度大幅增加,而多次HASH也使得建表和破解的难度都大幅增加。
在使用PBKDF2算法时,HASH一般会选用sha1或者sha256,随机盐的长度一般不能少于8字节,HASH次数至少也要1000次,这样安全性才足够高。一次密码验证过程进行1000次HASH运算,对服务器来说可能只需要1ms,但对于破解者来说计算成本增加了1000倍,而至少8字节随机盐,更是把建表难度提升了N个数量级,使得大批量的破解密码几乎不可行,该算法也是美国国家标准与技术研究院推荐使用的算法。
具体来说,PBKDF2算法的特点包括:
- 基于密码:PBKDF2使用用户输入的密码作为输入之一,这是它与其他密钥派生算法的一个重要区别。
- 多次迭代:算法会对密码和盐进行多次哈希运算,迭代次数越高,计算开销越大,从而增加了暴力破解的难度。
- 使用随机盐:盐是一个随机生成的序列,加入到密码的哈希过程中,以防止相同的密码生成相同的密钥。这有助于抵御彩虹表攻击。
- 输出固定长度的密钥:PBKDF2可以生成固定长度的密钥,以适应不同的加密需求。
虽然PBKDF2本身不是一种加密方式,但它在加密系统中扮演着重要的角色。例如,在存储用户密码时,可以使用PBKDF2将密码转换为密钥,然后再使用这个密钥来加密存储的敏感信息。这样,即使攻击者获取了存储的加密信息,也很难通过逆向工程来恢复原始密码。
(5):bcrypt、scrypt等算法
bcrypt和scrypt都是现代密码学中广泛使用的加密算法,它们各自具有独特的特点和优势。以下是对这两种算法的详细分析:
bcrypt算法
-
基本原理:
- bcrypt是一种基于Blowfish加密算法的密码哈希函数,专为密码存储设计。
- 它使用密码和一个随机生成的盐值作为输入,通过多次迭代哈希运算生成一个固定长度的密码哈希值。
-
安全性:
- 由于引入了盐值和可调节的工作因子(cost值),bcrypt能够有效抵抗彩虹表攻击和暴力破解。
- 盐值使得相同的密码在每次加密时都会生成不同的哈希值。
- 工作因子增加了哈希运算的次数,从而提高了破解的难度。
-
性能:
- bcrypt的运算速度相对较慢,这是为了增加破解的难度而故意设计的。
- 然而,在大量用户验证密码时,bcrypt使用了缓存机制来保持高效率。
-
应用场景:
- bcrypt适用于各种需要存储密码或进行身份验证的场景,如用户注册、登录和密码重置。
scrypt算法
-
基本原理:
- scrypt是由Colin Percival为他的备份服务Tarsnap开发的加密算法,是一种基于密码学的哈希函数。
- 它结合了伪随机数生成、哈希函数迭代以及大量的内存操作来增加破解难度。
-
安全性:
- scrypt在计算复杂度和内存使用量上都较高,这使其在面对暴力破解和彩虹表攻击时具有更高的抵抗力。
- 它还提供了更灵活的参数调整功能,以适应不同的安全需求和应用场景。
-
性能:
- scrypt的加密过程需要较长的计算时间和较多的内存占用,这使得并行计算多个摘要变得困难。
- 然而,这种设计也增加了攻击者的成本和难度。
-
应用场景:
- scrypt在加密货币和区块链系统中得到了广泛应用,如狗狗币和莱特币就采用了scrypt算法来确保网络的去中心化和安全性。
- 此外,它还可以用于生成安全的密钥、保护敏感数据的存储和传输,以及身份验证和访问控制。
比较与分析
- 安全性:在安全性方面,scrypt相对于bcrypt具有更高的计算复杂度和内存使用量,因此在某些场景下可能更难以被破解。然而,这并不意味着bcrypt不安全,它仍然是一种非常强大的密码哈希算法。
- 性能:在性能方面,bcrypt的运算速度相对较慢,但使用了缓存机制来保持高效率。而scrypt则需要较长的计算时间和较多的内存占用,这可能在一些资源受限的环境中成为性能瓶颈。
- 应用场景:在应用场景方面,bcrypt更适用于存储密码和进行身份验证等常规任务。而scrypt则更适用于需要更高安全性的场景,如加密货币和区块链系统。
综上所述,bcrypt和scrypt都是优秀的加密算法,各自具有独特的特点和优势。在选择使用哪种算法时,需要根据具体的应用场景和安全需求进行综合考虑。
在日常开发中我们怎么选择,如果对于数据量不大的加密,比如用户登录中密码的加密,这几个是都可以选的,但是安全性考虑:
BCrypt > SHA-256 > Md5 ,其中MD5
Md5加密 VS BCrypt加密
main方法测试:
package com.zzyl.vo;
import org.springframework.security.crypto.bcrypt.BCrypt;
import org.springframework.util.DigestUtils;
public class PswdTest {
public static void main(String[] args) {
//md5加密
String md5Pswd1 = DigestUtils.md5DigestAsHex("123456".getBytes());
String md5Pswd2 = DigestUtils.md5DigestAsHex("123456".getBytes());
System.out.println(md5Pswd1);
System.out.println(md5Pswd2);
System.out.println(md5Pswd1.equals(md5Pswd2));
System.out.println("-------------------------------------");
String password1 = BCrypt.hashpw("123456", BCrypt.gensalt());
String password2 = BCrypt.hashpw("123456", BCrypt.gensalt());
System.out.println(password1);
System.out.println(password2);
System.out.println(password1.equals(password2));
}
}
结果如下:
e10adc3949ba59abbe56e057f20f883e
e10adc3949ba59abbe56e057f20f883e
true
-------------------------------------
$2a$10$rkB/70Cz5UvsE7F5zsBh8O2EYDoGus3/AnVrEgP5cTpsGLxM8iyG6
$2a$10$QIefMa.FmFIb2k2S9/jO7e1S3b0aeXCMtGS/ArKUyt6q28deYQrfy
false
md5对于同一个字符串加密多次都是相同的
BCrypt对于同一个字符串加密多次是不同的,主要是因为添加了随机盐(随机字符串),更加安全
其中BCrypt提供了一个方法,用于验证密码是否正确
boolean checkpw = BCrypt.checkpw("123456", "$2a$10$rkB/70Cz5UvsE7F5zsBh8O2EYDoGus3/AnVrEgP5cTpsGLxM8iyG6");
• 返回值为true,表示密码匹配成功
• 返回值为false,表示密码匹配失败
在日常开发中我们怎么选择,如果对于数据量不大的加密,比如用户登录中密码的加密,这几个是都可以选的,但是安全性考虑:
**BCrypt > SHA-256 > Md5
在选择MD5、SHA-256以及Spring Security的BCryptPasswordEncoder时,需要根据具体的应用场景和安全需求进行综合考虑。以下是对这三种算法的分析和选择建议:
MD5
特点:
- MD5是一种广泛使用的哈希算法,能够将任意长度的数据转换为128位的哈希值。
- 由于其算法相对简单,MD5的运算速度较快。
- 然而,MD5已被证明存在碰撞攻击的漏洞,即存在不同的输入数据但哈希值相同的情况。
选择建议:
- 由于MD5的安全性较低,不建议在需要高安全性的场景中使用,如密码存储、数字签名等。
- 对于一些简单的校验和验证场景,如果不需要高安全性,可以考虑使用MD5,但需注意其碰撞风险。
SHA-256
特点:
- SHA-256是SHA-2算法家族中的一员,能够生成256位的哈希值。
- SHA-256算法相对复杂,运算速度较MD5慢,但提供了更高的安全性。
- SHA-256是目前广泛使用的安全哈希算法之一,尚未发现有效的碰撞攻击方法。
选择建议:
- 对于需要较高安全性的场景,如密码存储、文件完整性校验等,SHA-256是一个较好的选择。
- SHA-256的哈希值长度较长,降低了碰撞概率,增加了数据的安全性。
Spring Security的BCryptPasswordEncoder
特点:
- BCryptPasswordEncoder是Spring Security框架提供的一种密码编码器,使用BCrypt算法对用户密码进行安全的哈希加密存储。
- BCrypt算法结合了随机的盐值和可调节的迭代次数,增加了密码破解的难度。
- BCryptPasswordEncoder生成的哈希密码长度较长(通常为60位),且每次加密的结果都不同,有效抵御了彩虹表攻击和暴力破解。
选择建议:
- 对于需要存储和验证用户密码的场景,BCryptPasswordEncoder是一个强烈推荐的选择。
- 它不仅提供了高安全性,而且易于集成到Spring Security框架中,通过简单的配置即可对用户密码进行编码和验证。
综合考虑
- 安全性:BCryptPasswordEncoder > SHA-256 > MD5。BCryptPasswordEncoder结合了盐值和迭代次数,提供了最高的安全性;SHA-256虽然较MD5安全,但仍存在被暴力破解的风险(尽管难度较高);MD5由于存在碰撞攻击的漏洞,安全性最低。
- 运算速度:MD5 > SHA-256 > BCryptPasswordEncoder。MD5的算法相对简单,运算速度最快;SHA-256算法较复杂,运算速度较慢;BCryptPasswordEncoder由于结合了盐值和迭代次数,运算速度最慢。
- 应用场景:根据具体需求选择。对于需要高安全性和密码存储的场景,选择BCryptPasswordEncoder;对于文件完整性校验等需要较高安全性的场景,选择SHA-256;对于一些简单的校验和验证场景且对安全性要求不高时,可以考虑使用MD5(但需注意碰撞风险)。
综上所述,在选择MD5、SHA-256以及Spring Security的BCryptPasswordEncoder时,应根据具体的应用场景和安全需求进行综合考虑。在大多数情况下,BCryptPasswordEncoder是存储和验证用户密码的最佳选择。