【密码学】BCrypt算法java实现

一、概述

        你会用什么样的算法来为你的用户保存密码?如果你还在用明码的话,那么一旦你的网站被hack了,那么你所有的用户口令都会被泄露了,这意味着,你的系统或是网站就此完蛋了。所以,我们需要通过一些不可逆的算法来保存用户的密码。比如:MD5, SHA1, SHA256, SHA512, SHA-3,等Hash算法。这些算法都是不可逆的。系统在验证用户的口令时,需要把Hash加密过后的口令与后面存放口令的数据库中的口令做比较,如果一致才算验证通过。但你觉得这些算法好吗?我说的是:MD5, SHA1, SHA256, SHA512, SHA-3。如果你使用的是MD5算法来加密你的口令,如果你的口令长度只有小写字母再加上数字,假设口令的长度是6位,那么在目前一台比较新一点的PC机上,穷举所有的口令只需要40秒钟。而据我们了解,几乎有90%以上的用户只用小写字母和数字来组织其口令。对于6位长度的密码只需要最多40秒就可以破解了,这可能会吓到你。如果你愿意花2000美金和一周的时间来构建一个CUDA,那么,你可以在你组建的这个集群中使用进行密码穷举运算,其速度是,1秒钟可以计算7亿个口令。对于目前实际当中使用的比较复杂的口令,其破解率也可以高达每秒一个。当然,这里说的算法是MD5,SHA之类的算法。    

        那么,对于这样的一种情况来说,我们怎么办?我们还是有办法的。我们知道MD5,SHA的算法速度太快了。所以,我们需要一个“慢一点”的加密算法。bcrypt是这样的一个算法,因为它很慢,对于计算机来说,其慢得有点BT了,但却慢得刚刚好!对于验证用户口令来说是不慢的,对于穷举用户口令来说,其会让那些计算机变得如同蜗牛一样。因为bcrypt采用了一系列各种不同的Blowfish加密算法,并引入了一个work factor,这个工作因子可以让你决定这个算法的代价有多大。因为这些,这个算法不会因为计算机CPU处理速度变快了,而导致算法的时间会缩短了。因为,你可以增加work factor来把其性能降下来。那么,bcrypt到底有多慢?如果和MD5一起来比较的话,如果使用值为12的work factor的话,如果加密“cool”的话,bcrypt需要0.3秒,而MD5只需要一微秒(百万分之一秒)。也就是说,前面我们说的那个只需要40秒就可以穷举完所有的可能的MD5编码的口令的算法,在使用bcrypt下,需要12年。这就是bcrypt给你带来的选择,你可以一个安全的口令和一个快速的加密算法,或是一个不怎么安全的口令和一个性能不好的加密算法。

        总而言之,bcrypt是一个哈希算法,一个明文映射多个密文,但是相同密文不同密文校验值BCrypt.checkpw一致;相比于MD5,更安全,速度慢。

二、JAVA实现

1.官网下载源码:http://www.mindrot.org/projects/jBCrypt/

2.将BCrypt.java拷贝到项目下,使用

package EncryptAndDecrypt;

import java.util.Scanner;
/*
* BCrypt Java实现
* BCrypt也是一种哈希算法,相比MD5更安全,速度慢
* */
public class UseBCrypt {
    public static void main(String args[]){
        Scanner scanner=new Scanner(System.in);
        System.out.println("请输入密码:");
        String password=scanner.nextLine();//明文
        System.out.println("请输入待验证密码:");
        String candidate=scanner.nextLine();
        // 第一次哈希一个password
        String hashed = BCrypt.hashpw(password, BCrypt.gensalt());//密文

        // gensalt's log_rounds parameter determines the complexity
        // the work factor is 2**log_rounds, and the default is 10
        String hashed2 = BCrypt.hashpw(password, BCrypt.gensalt(12));
        System.out.println(hashed);
        System.out.println(hashed2);
        //密码密文匹配检测
        if (BCrypt.checkpw(candidate, hashed))
            System.out.println("It matches");
        else
            System.out.println("It does not match");
    }
}
请输入密码:
123456
请输入待验证密码:
234563
$2a$10$RbX30iBRU0/rZtY9itIYF.F7PlqZAkHuYQFDDSE9ESOU9z.i.1gZu
$2a$12$waisaCtTw8EvT/ddNEz1kOFPdIAHHIfPQk0QhOLGSAcgDPjCv5s0K
It does not match
转自: https://yq.aliyun.com/articles/48942

你可能感兴趣的:(密码学)