Melvin Mah
Melvin Mah

Reputation: 125

Can plaintexts be set or converted into salts in BCrypt?

I have a requirement for our password encryption exercise where the salt for a password is to be static and set as (business_id+business_start_date) values depending on the client's business id and start date. In the BCrypt documentation, it's said that BCrypt has salts built into the generated hashes to prevent rainbow table attacks. Most examples use the gensalt(int log_rounds) function.

IMO, I definitely would use a dynamic salt like others would do, as it is much easier to implement. However, if the insistence of implementing a static salt hash remains, is there a way to get BCrypt to accept static hashes OR; if not possible, what other encryptions can I use to for that requirement?

The application is mainly 80% reading content, with a little amount of create, update, delete operations.

I just did a test where I attempted to hash the password with the static salt.

This method is used in the BCrypt utility class:

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

The salt, which I was testing was in plain text eg.(busId:3,businessDate:2019-02-04)

String salt = new StringBuilder(busId).append(businessDate).toString();

I also had this method as standby, with the number of rounds (workload) set to 10.

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

The Invalid Salt Version error gets thrown into the exception when the hashpw() function was executed.

Upvotes: 2

Views: 303

Answers (1)

Yunus Karakaya
Yunus Karakaya

Reputation: 531

I've implemented base on kelalaka's comment. This is Bcrypt library always requires a formated salt. Depending on your plaintext size, if it is less then the BCRYPT_SALT_LEN,The rest of rnd filled with random bytes, the rest as in the library.

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();

}

Upvotes: 1

Related Questions