Encoding a password with argon2 and save on PostgreSQL

747 views Asked by At

I'm trying to encox user password to save in postgresql database. Using kotlin and argon2. I did the functions and in the tests, it works perfectly. But when I save it in the database, and I try to compare the passwords, it always gives an error. Could anyone help?

I created the following functions:

private val argon2 = Argon2Factory.create(Argon2Factory.Argon2Types.ARGON2id, 32, 64)

fun String.encode(): String = argon2.hash(3, 64 * 1024, 1, this.toCharArray())

fun String.checkEncoding(hash: String): Boolean = argon2.verify(hash, this.toCharArray())

and in tests, everything works perfectly

class HashingTest : ShouldSpec({
  context("Encoding a string") {
    should("encode correctly") {
      val dataOne = "S@!sc_%kah"
      val encondeOne = dataOne.encode()
      val dataTwo = "S@!sc_%kah"
      dataTwo.checkEncoding(encondeOne) shouldBe true // works fine!
    }
  }
})

When I save to the database, and try to compare, I always get an error

//ENTITY

data class User(
  override val id: UUID,
  val username: String,
  val password: String,
) : IEntity


//INSERT SCRITP -> EXPOSED FRAMEWORK

private fun newUser(schema: String, entity: User) {
  val table = toUserTable(schema)
  table
    .insert {
      it[id] = entity.id
      it[username] = entity.username 
      it[password] = entity.password.encode()
    }
}

//FIND USER

fun findUser(schema: String, model: SignInModel): User? {
  val table = toUserTable(schema)
  val user = table
    .select { table.username eq model.username }
    .firstNotNullOfOrNull { toUser(schema, it) }
  val verifying = model.password.checkEncoding(user!!.password) // ERROR HERE, ALWAYS RETURNS FALSE
  return when (verifying) {
    true -> user
    false -> null
  }
}


1

There are 1 answers

0
Last Noob Ninja On BEST ANSWER

I don't know if you used your findUser() and newUser() in a transaction but queries must be called in a transaction like below:

private fun newUser(schema: String, entity: User) {
    val table = toUserTable(schema)
    transaction {
        table
           .insert {
               it[id] = entity.id
               it[username] = entity.username 
               it[password] = entity.password.encode()
            }
    }
}

and:

fun findUser(schema: String, model: SignInModel): User? {
  val table = toUserTable(schema)
  val user = transaction {
      table
        .select { table.username eq model.username }
        .firstNotNullOfOrNull { toUser(schema, it) }
  }

  val verifying = model.password.checkEncoding(user!!.password)
  return when (verifying) {
    true -> user
    false -> null
  }
}