Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

241
Vistas
How do I handle salting a password hash in Vapor 3?

I'm building a basic authentication setup similar to how it's used in Vapor's auth-template template (from here). I have everything set up the same way as in the template.

However, I would like to add salt. I can generate a salt for a user upon creation:

static func create(_ req: Request, newUserRequest user: CreateUserRequest) throws -> Future<User.Public> {
    return User.query(on: req).filter(\.username == user.username).first().flatMap { existingUser in
        guard existingUser == nil else {
            throw Abort(.badRequest, reason: "A user with the given username already exists.")
        }

        guard user.password == user.passwordVerification else {
            throw Abort(.badRequest, reason: "Given passwords did not match.")
        }

        let count = 16
        var pw_salt_data = Data(count: count)
        let _ = pw_salt_data.withUnsafeMutableBytes { mutableBytes in
            SecRandomCopyBytes(kSecRandomDefault, count, mutableBytes)
        }
        let pw_salt = try BCrypt.hash(pw_salt_data.base64EncodedString())

        let pw_hash = try BCrypt.hash(pw_salt + user.password)

        return User(id: nil, username: user.username, pw_hash: pw_hash, pw_salt: pw_salt, email: user.email).save(on: req).toPublic()
    }
}

But there's no way to retrieve that salt when performing authentication during login:

static func login(_ req: Request) throws -> Future<UserToken> {
    let user = try req.requireAuthenticated(User.self)
    let token = try UserToken.create(userID: user.requireID())
    return token.save(on: req)
}

I want the salt to be randomly generated for each user and stored in the database as a separate column from the hashed password to be used later during authentication.

Is there a standardized way to handle salting a password hash in Vapor 3?

over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

The way it works in Vapor is that each BCrypt hash has a unique salt that’s saved with the password in the database. The BCrypt default functions in Vapor expect this.

If you want to go down a different route have a look at the function to hash a password - that takes a salt. You can then save that in its own field and retrieve and when you verify the password. Honestly I’d say to just use the defaults unless you have a very specific reason not to

over 4 years ago · Santiago Trujillo Denunciar

0

You hash the password using BCrypt. BCrypt is already part of the Vapor dependencies.

BCrypt.hash("vapor", cost: 4)

This will hash the string "vapor", using a randomly generated salt, with complexity 4. Choosing the cost is subjective and arbitrary but it is recommended that real-world secure applications should have a cost factor above 10-12. If you don't like the salt being randomly generated by BCrypt, and you want to generate your own salt, you can provide the salt to the hash function, which has the following signature:

public func hash(_ plaintext: LosslessDataConvertible, cost: Int = 12, salt: LosslessDataConvertible? = nil) throws -> String 

Documentation says that the salt must be 16-bytes if manually provided. This is a sample hash:

$2a$04$/nqhWqplnughhq6mlKmi8.raprxoG/dczY8kdbOKm.zC5sPu.2IBi

As you can see it includes auxiliary information such as the complexity, the type of the algorithm and the salt, everything necessary to do the verification. If you provided your own salt it will also be part of the final hash and you don't need to separately provide it. You can do verification as written below.

try BCrypt.verify("vapor", created: hashedPasswordSavedInDatabase)
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda