密码的加密

用户注册时(管理员添加新的账号信息时)的密码必须经过某种算法进行编码,并将得到的结果存储到数据库,而不允许将原始密码直接存储到数据库中!

原始密码通常可以称之为密码的原文,或称之为明文密码,经过编码处理的结果可称之为密文

如果直接存储明文密码,容易导致用户账号被窃取的安全问题,基于当下主流的网络技术,这类安全问题通常是企业内部管理问题导致的!简单来说,对密码进行加密处理,主要防的就是内部员工(例如能够直接接触到数据库服务器的员工,无论是进入机房或是远程登录)。

早在2011(2012?)年,CSDN就被暴出了明文的账号密码的导出文件!

对明文密码进行编码处理时,不可以使用任何加密算法,因为所有加密算法都是可以逆向运算的,即:根据算法类型、加密参数、密文,可以通过运算得到密码原文!通常,加密算法只是用于保障数据在传输过程中的安全性!

对于需要存储下来的密码,且只需要验证原密码是否匹配,不需要(不允许)通过逆向运算根据密文得到原文时,应该使用消息摘要算法对密码原文进行编码处理!

消息摘要算法的典型特征有:

  • 消息相同时,摘要必然相同
  • 使用固定的某种消息摘要算法时,无论消息的长度多少,摘要的长度是固定的
  • 消息不同时,摘要极大概率不会相同
    • 理论上,必然存在N个不同的消息,通过编码,得到的摘要是完全相同的
    • 由于摘要的种类也非常多,设计得非常好的算法会使得这种概率非常低
  • 所有消息摘要算法都是不可以逆向运算的

消息摘要算法的结果通常会使用十六进制数来表示,通常,运算结果相同简单的消息摘要算法的结果长度也有32位十六进制数组成,还原成二进制数就是128个二进制数组成,这样的算法称之“128位算法”,同理,如果某个结果是由64个十六进制数组成,还原成二进制就是256个二进制数,则称之为“256位算法”。

以128位算法为例,其运算结果的种类将高达2的128次方种,即:340282366920938463463374607431768211456,以现有的计算机的算法,是不可能进行穷举式的暴力破解的!如果是256位算法,甚至更高位数的算法,更加不可能暴力破解!

常见的消息算法有:

  • MD(Message Digest)系列
    • MD2(128位,不推荐) / MD4(128位,不推荐) / MD5(128位)
  • SHA(Secure Hash Algorithm)家族
    • SHA-1(160位,不推荐) / SHA-256(256位) / SHA-384(384位) / SHA-512(512位)

在Spring Boot项目中,已有DigestUtils工具类,提供了使用MD5算法进行编码的API:

关于消息摘要算法的破解:所有消息摘要算法都是不可逆向运算的,尝试将消息摘要运算结果运算还原出原本数据的思路本身就是错误的!一个成熟可靠的消息摘要算法,理论上,极难找出2个不同的原始数据对应相同的摘要,如果出现了这样的情况,称之“碰撞”,关于消息摘要算法的破解,本身是研究碰撞,与逆向运算无关!

如果需要根据使用消息算法编码得到的密文还原出密码的原文,常见做法是使用穷举法,记录各原文与密文的对应关系,当需要“破解”时,本质上是在执行查询操作!

原文(消息)密文(摘要)
000000670b14728ad9902aecba32e22fa4f6bd
11111196e79218965eb72c92a549dd5a330112
222222e3ceb5881a0a1fdaad01296d7554868d
3333331a100d2c0dab19c4430e7d73762b3423
44444473882ab1fa529d7273da0db6b49cc4f3
5555555b1b68a9abf4d2cd155c81a9225fd158

其实,这样的做法能够“破解”的密码是非常有限的!假设密码可以使用所有的可打印字符(共计95种),如果密码的长度只有1位,则可以有95种不同的密码,如果密码的长度有2位,则可以有95 x 95种不同的密码,以此类推,如果密码的长度有6位,则可以有735,091,890,625种(7350亿种)不同的密码,如果密码的长度有8位,则可以有6,634,204,312,890,625种(约6634万亿种)不同的密码,所以,如果需要反查出任何8位长度的密码,则需要记录下6600多万亿条数据才可以!

所以,最有效的保证密码安全的做法是要求用户使用安全强度更高的密码,例如密码至少有8位,且密码中必须同时包含字母、数字、标点符号等。

为了进一步提高密码的安全性,在编码过程中,还应该使用“盐值”,盐值是一个自定义的字符串,它应该与原密码一并作为消息摘要算法的被运算数据,则对于算法而言,被运算数据就不再只是简单的密码原文而已,则密码原文与盐值组合的结果,例如:

String salt = "75ifDV8rqHLfrFw87TFylDGSLGah";
String rawPassword = "000000";
String encodedPassword = DigestUtils
            .md5DigestAsHex((salt + rawPassword + salt).getBytes());
System.out.println("原文:" + rawPassword);
System.out.println("密文:" + encodedPassword);

不过,尽管加盐可以非常有效的防止密码被反查,但是,如果算法、运算参数(例如盐值等)、密文同时被泄露,依然可能会被穷举式的暴力破解

目前,更推荐使用BCrypt算法对密码加密进行处理,这种算法默认就使用了随机的盐,并且,将盐值作为加密结果的一部分,以此保证密文是可以被验证的!更重要的是,BCrypt算法被设计为非常非常慢的算法,

总的来说,要最大限度的保证密码安全,应该:

  • 要求用户使用安全强度更高的密码
  • 加盐
  • 多重加密
  • 使用安全系数更强的算法
  • 综合以上做法
  • 69
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

菜鸟程序员z

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值