To protect passwords we can add salt while hashing. Different salt texts lead to different results for the very same password. But I noticed that I get the same result for different salt texts with bcrypt
. See this example:
library("bcrypt")
my_password <- "password1"
my_salt_1 <- paste0("$2a$10$", paste0(letters[1:22], collapse= ""), collapse= "")
my_salt_2 <- paste0("$2a$10$", paste0(letters[c(1:21, 21)], collapse= ""), collapse= "")
hashpw(my_password, my_salt_1) == hashpw(my_password, my_salt_2)
TRUE
In fact it is easy to create more salts that result in the same hashing password. For example, we get the same hashing password using the salt paste0("$2a$10$", paste0(letters[c(1:21, 26)], collapse= ""), collapse= "")
. Why is this happening? Is this only because the salts are qiute similiar or is here something else going on?
CodePudding user response:
If you jump through a lot of the source code (and I'm not 100% sure I did correctly but it seems to match up) it looks like the main issue that the salt bytes are base64 encoded. The two strings you created actually have the exact same base64 decoded value (see Can two different BASE 64 encoded strings result into same string if decoded). Observe
s1 <- "abcdefghijklmnopqrstuv"
s2 <- "abcdefghijklmnopqrstuu"
openssl::base64_decode(s1)
# [1] 69 b7 1d 79 f8 21 8a 39 25 9a 7a 29 aa bb 2d
openssl::base64_decode(s2)
# [1] 69 b7 1d 79 f8 21 8a 39 25 9a 7a 29 aa bb 2d
Thus you are using the identical salt. If you want to get a random salt, the bcrypt::gensalt()
function is a safer alternative
(my_salt_1 <- gensalt(10))
# [1] "$2a$10$XBGMfrY0DIVHX3KZVwKmM."
(my_salt_2 <- gensalt(10))
# [1] "$2a$10$NM8t5AsKmHJHs0d/hIFlbe"
hashpw(my_password, my_salt_1) == hashpw(my_password, my_salt_2)
# [1] FALSE