I’m using Ktor 2 and JWT. I want to hash the passw...
# ktor
d
I’m using Ktor 2 and JWT. I want to hash the password when a user creates an account. And then verify it when the user logs in. Which function/package should I user to hash passwords ?
s
I am using BCrypt, https://github.com/patrickfav/bcrypt. Same crypto that Spring commonly uses afaik.
tl;dr bcrypt is better than PBKDF2 because PBKDF2 can be better accelerated with GPUs. As such, PBKDF2 is easier to brute force offline with consumer hardware.
👍 2
l
Note that bcrypt is getting older. Scrypt does a good job of fighting specially-designed ASICs. I personally use argon2, since it’s theoretically more secure, but note that it’s only been around for 5-6 years, so it hasn’t been as well tested as scrypt or bcrypt.
👍 1
s
Thanks for sharing!
d
Anyone can see what I’m doing wrong ? I have :
Copy code
post("/login") {
        val authenticatingUser = call.receive<AuthenticatingUser>()
        val dbUser = userDSL.findUserByEmail(authenticatingUser.email)
        val bcryptHashString = BCrypt.withDefaults().hashToString(12, authenticatingUser.password.toCharArray())
        val result: BCrypt.Result = BCrypt.verifyer().verify(dbUser?.password?.toCharArray(), bcryptHashString)
        if(!result.verified) {
            throw AuthorizationException("Sorry you are not authorized")
        }
but I always get
result.verified
equal to false. And I created (seeded) the user like so
Copy code
val password = "secret"
val bcryptHashString = BCrypt.withDefaults().hashToString(12, password.toCharArray())
userDSL.create("johndoe", "<mailto:johndoe@test.com|johndoe@test.com>", bcryptHashString)
s
I am using the following successfully
Copy code
val hash = BCrypt.withDefaults().hash(12, "secret".toByteArray())
val result = BCrypt.verifyer().verify("secret".toByteArray(), hash)
@Landry Norris do you know a Script lib for JVM? I don't want to depend on Spring for it.
l
I personally haven’t used scrypt. I would imagine bouncy castle would have something for scrypt.
👍 1
d
@simon.vergauwen Hopefully, I’m not asking too much but how to you save your password. My User password type is a String and I’m trying to save the hashedPassword like so :
Copy code
val hashedPassword = BCrypt.withDefaults().hash(12, newUser.password.toByteArray())
        transaction {
            Users.insert {
                it[username] = username
                it[email] = email
                it[password] = hashedPassword
            }
        }
but IntelliJ complains:
Copy code
None of the following functions can be called with the arguments supplied.
set(Column<TypeVariable(ID)>, TypeVariable(E))   where S = TypeVariable(S), ID = TypeVariable(ID), E = TypeVariable(E) for    fun <S, ID : EntityID<S>, E : Expression<S>> set(column: Column<ID>, value: E): Unit defined in org.jetbrains.exposed.sql.statements.InsertStatement
set(Column<TypeVariable(ID)>, TypeVariable(E))   where S = TypeVariable(S), ID = TypeVariable(ID), E = TypeVariable(E) for    fun <S : Comparable<S>, ID : EntityID<S>, E : S?> set(column: Column<ID>, value: E): Unit defined in org.jetbrains.exposed.sql.statements.InsertStatement
set(Column<TypeVariable(S)>, TypeVariable(S))   where S = TypeVariable(S) for    fun <S> set(column: Column<S>, value: S): Unit defined in org.jetbrains.exposed.sql.statements.InsertStatement
set(Column<TypeVariable(S)>, Query)   where S = TypeVariable(S) for    fun <S> set(column: Column<S>, value: Query): Unit defined in org.jetbrains.exposed.sql.statements.InsertStatement
set(Column<TypeVariable(T)>, TypeVariable(E))   where T = TypeVariable(T), S = TypeVariable(S), E = TypeVariable(E) for    fun <T, S : T, E : Expression<S>> set(column: Column<T>, value: E): Unit defined in org.jetbrains.exposed.sql.statements.InsertStatement
set(CompositeColumn<TypeVariable(S)>, TypeVariable(S))   where S = TypeVariable(S) for    fun <S> set(column: CompositeColumn<S>, value: S): Unit defined in org.jetbrains.exposed.sql.statements.InsertStatement
No set method providing array access
s
Users.password
should be a
ByteArray
. The type of
hashedPassword
is a byte array
I am using SqlDelight 2.0.0-alpha2 with Postgres with
bytea
d
Ok figured it out… Thanks a lot @simon.vergauwen
👍 1