Current section
Files
Jump to
Current section
Files
lib/fernet/passphrase.ex
defmodule Fernet.Passphrase do
@moduledoc """
This module provides function to encrypt and decrypt a string using a passphrase.
The implementation is designed to work cross-language; currently there are
packages for the browser (using the WebCrypto API), NodeJS and PHP.
## Details
The passphrase is converted to a key using PBKDF2 with a random salt, and then
this is used as a key for Fernet encryption.
"""
@doc ~S"""
Encrypt the given text with the given passphrase.
## Options
- iterations: The number of iterations to use during PBKDF2 key derivation (default 10000).
"""
def encrypt(passphrase, plaintext, options \\ []) do
iterations = Keyword.get(options, :iterations, 10000)
salt = :crypto.strong_rand_bytes(16)
with {:ok, key} <-
:pbkdf2.pbkdf2(
:sha256,
passphrase,
salt,
iterations,
32
),
{:ok, _, token} <- Fernet.generate(plaintext, key: key) do
%{
config: %{
iterations: iterations,
salt: salt |> Base.encode64()
},
token: token
}
|> Jason.encode()
end
end
@doc ~S"""
Decrypt the given ciphertext with the given passphrase.
"""
def decrypt(passphrase, ciphertext) do
%{"config" => %{"iterations" => iterations, "salt" => salt}, "token" => token} =
Jason.decode!(ciphertext)
with {:ok, key} <-
:pbkdf2.pbkdf2(
:sha256,
passphrase,
salt |> Base.decode64!(),
iterations,
32
),
{:ok, {_, plaintext}} <- Fernet.verify(token, key: key) do
{:ok, plaintext}
end
end
end