4.1 KiB
Hash
Hashing is a one way method of converting arbitrary data into a fixed size format. Unlike ciphers, data that is hashed cannot be retrieved from the resulting digest. Hashes can be used to create keys, file identifiers, or store credentials.
Hash function diagram from Wikipedia.
!!! warning Avoid storing password hashes if possible. If you must, please make sure to research the state of the art before continuing.
Make
To hash a string, use the hash property on Droplet.
let digest = try drop.hash.make("vapor")
print(digest.string)
Checking
Some hashing algorithms create different hash digests for the same message. Because of this, it is necessary to check your hashes using the check method.
let matches = try drop.hash.check("vapor", matchesHash: digest)
CryptoHasher
By default, Vapor uses a SHA-256 hasher. You can change this in the configuration files or by giving the Droplet a different hasher.
Configuration
Config/droplet.json
{
...,
"hash": "crypto",
...
}
Config/crypto.json
{
"hash": {
"method": "sha256",
"encoding": "hex",
"key": "password"
},
...
}
Encoding
The CryptoHasher supports three methods of encoding.
hexbase64plain
Key
Supplying a key will cause the hasher to produce keyed hashes using HMAC. Some hashers require a key.
Supported
| Name | Method | Requires Key |
|---|---|---|
| SHA-1 | sha1 | no |
| SHA-224 | sha224 | no |
| SHA-256 | sha256 | no |
| SHA-384 | sha384 | no |
| SHA-512 | sha512 | no |
| MD4 | md4 | no |
| MD5 | md5 | no |
| RIPEMD-160 | ripemd160 | no |
| Whirlpool | whirlpool | yes |
| Streebog-256 | streebog256 | yes |
| Streebog-512 | streebog512 | yes |
| GostR341194 | gostr341194 | yes |
Manual
Hashers can be swapped without the use of configuration files.
Hash
let drop = try Droplet()
drop.hash = CryptoHasher(
hash: .sha256,
encoding: .hex
)
HMAC
let drop = try Droplet()
drop.hash = CryptoHasher(
hmac: .sha256,
encoding: .hex,
key: "password".makeBytes()
)
BCryptHasher
BCrypt is a password hashing function that automatically incorporates salts and offers a configurable work factor. The work factor can be used to increase the computation required to generate a hash.
!!! seealso Learn more about key stretching on Wikipedia.
Configuration
To use the BCryptHasher change the "hash" key in the droplet.json configuration file.
Config/droplet.json
{
...,
"hash": "bcrypt",
...
}
To configure the work factor, add a bcrypt.json file.
Config/bcrypt.json
{
"workFactor": 8
}
!!! tip You can use different BCrypt work factors for production and development modes to keep password hashing fast while working on a project.
Manual
You can manually assign a BCryptHasher to drop.hash.
let drop = try Droplet()
drop.hash = BCryptHasher(workFactor: 8)
Advanced
Custom
You can also create your own hasher. You just need to conform to the Hash protocol.
/// Creates hash digests
public protocol HashProtocol {
/// Given a message, this method
/// returns a hashed digest of that message.
func make(_ message: Bytes) throws -> Bytes
/// Checks whether a given digest was created
/// by the supplied message.
///
/// Returns true if the digest was created
/// by the supplied message, false otherwise.
func check(_ message: Bytes, matchesHash: Bytes) throws -> Bool
}