Java 在BCrypt中,明文可以设置或转换为盐吗?

Java 在BCrypt中,明文可以设置或转换为盐吗?,java,security,bcrypt,Java,Security,Bcrypt,我对我们的密码加密练习有一个要求,其中密码的salt是静态的,并根据客户的业务id和开始日期设置为(business\u id+business\u start\u date)值。在BCrypt文档中,据说BCrypt在生成的哈希中内置了盐,以防止彩虹表攻击。大多数示例使用gensalt(int log_)函数 在我看来,我肯定会像其他人一样使用动态salt,因为它更容易实现。然而,如果仍然坚持实现静态salt散列,有没有办法让BCrypt接受静态散列或;如果不可能,我可以使用哪些其他加密来满足

我对我们的密码加密练习有一个要求,其中密码的salt是静态的,并根据客户的业务id和开始日期设置为(
business\u id+business\u start\u date
)值。在BCrypt文档中,据说BCrypt在生成的哈希中内置了盐,以防止彩虹表攻击。大多数示例使用gensalt(int log_)函数

在我看来,我肯定会像其他人一样使用动态salt,因为它更容易实现。然而,如果仍然坚持实现静态salt散列,有没有办法让BCrypt接受静态散列或;如果不可能,我可以使用哪些其他加密来满足该要求

应用程序主要是80%的阅读内容,还有少量的创建、更新、删除操作

我刚刚做了一个测试,尝试用静态salt散列密码

此方法在BCrypt实用程序类中使用:

public static String hashPassWord(String textPassword, String salt){
        String hashPassword = BCrypt.hashpw(textPassword, salt);
        return hashPassword;
}
我正在测试的salt是纯文本的,例如(busId:3,businessDate:2019-02-04)

我还将此方法作为备用方法,将轮数(工作负载)设置为10

public static String hashPassword(String textPassword){
        String salt = BCrypt.gensalt(workload);
        String hashPassword = BCrypt.hashpw(textPassword, salt);
        return hashPassword;
}

执行hashpw()函数时,无效的Salt版本错误被抛出异常。

我已经根据kelalaka的注释实现了。这是Bcrypt库始终需要格式化的盐。根据您的明文大小,如果它小于BCRYPT_SALT_LEN,则rnd的其余部分填充随机字节,其余部分与库中相同

public static String gensalt(int log_rounds, SecureRandom random, String plaintextSalt) {

    byte[] plaintextByte = plaintextSalt.getBytes();
    byte rnd[] = new byte[BCRYPT_SALT_LEN];

    //Use all of the string if size >= of the reqired rnd size
    if (plaintextByte.length >= BCRYPT_SALT_LEN) {
        System.arraycopy(plaintextByte, 0, rnd, 0, rnd.length);

    } else {
        //copy all of the string byte array
        System.arraycopy(plaintextByte, 0, rnd, 0, plaintextByte.length);

        //fill the rest with random
        byte[] tempArray = new byte[BCRYPT_SALT_LEN - plaintextByte];
        random.nextBytes(tempArray);
        System.arraycopy(tempArray, 0, rnd, plaintextByte.length, temp.length);
    }

    StringBuffer rs = new StringBuffer();

    rs.append("$2a$");
    if (log_rounds < 10)
        rs.append("0");
    if (log_rounds > 30) {
        throw new IllegalArgumentException(
                "log_rounds exceeds maximum (30)");
    }
    rs.append(Integer.toString(log_rounds));
    rs.append("$");
    rs.append(encode_base64(rnd, rnd.length));
    return rs.toString();

}
公共静态字符串gensalt(int log_rounds、SecureRandom、String plaintextsat){
字节[]明文字节=明文盐。getBytes();
字节rnd[]=新字节[BCRYPT_SALT_LEN];
//如果大小>=为所需rnd大小,则使用所有字符串
如果(明文字节.length>=BCRYPT\u SALT\u LEN){
System.arraycopy(明文字节,0,rnd,0,rnd.length);
}否则{
//复制所有字符串字节数组
System.arraycopy(plaintextByte,0,rnd,0,plaintextByte.length);
//用随机数填充其余部分
byte[]tempArray=新字节[BCRYPT_SALT_LEN-plaintextByte];
随机.nextBytes(临时数组);
System.arraycopy(临时数组,0,rnd,明文字节长度,临时长度);
}
StringBuffer rs=新的StringBuffer();
卢比($2a$);
如果(对数轮数<10)
卢比(“0”);
如果(对数轮数>30){
抛出新的IllegalArgumentException(
“对数轮数超过最大值(30)”;
}
rs.append(Integer.toString(log_轮));
卢比(“$”);
rs.append(encode_base64(rnd,rnd.length));
返回rs.toString();
}

您需要创建
getsalt
函数。此函数返回的不是从中可以看到的普通字符串。最简单的方法是在第718行之后用随机字节对数据进行x-oring,或者用salt替换随机字节。
public static String gensalt(int log_rounds, SecureRandom random, String plaintextSalt) {

    byte[] plaintextByte = plaintextSalt.getBytes();
    byte rnd[] = new byte[BCRYPT_SALT_LEN];

    //Use all of the string if size >= of the reqired rnd size
    if (plaintextByte.length >= BCRYPT_SALT_LEN) {
        System.arraycopy(plaintextByte, 0, rnd, 0, rnd.length);

    } else {
        //copy all of the string byte array
        System.arraycopy(plaintextByte, 0, rnd, 0, plaintextByte.length);

        //fill the rest with random
        byte[] tempArray = new byte[BCRYPT_SALT_LEN - plaintextByte];
        random.nextBytes(tempArray);
        System.arraycopy(tempArray, 0, rnd, plaintextByte.length, temp.length);
    }

    StringBuffer rs = new StringBuffer();

    rs.append("$2a$");
    if (log_rounds < 10)
        rs.append("0");
    if (log_rounds > 30) {
        throw new IllegalArgumentException(
                "log_rounds exceeds maximum (30)");
    }
    rs.append(Integer.toString(log_rounds));
    rs.append("$");
    rs.append(encode_base64(rnd, rnd.length));
    return rs.toString();

}