Skip to content

Explicit encryption required? #33

@moritzploss

Description

@moritzploss

First of all, thanks for this great tutorial! I learned a lot following along!

After going through the code several times, I'm wondering why we would need to explicitly encrypt/decrypt field values of our custom EncryptedField type before saving them in the database. Isn't that why we define our custom Ecto Types to begin with, so that we don't need to encrypt/decrypt values manually and explicitly, but rather leave these tasks to the callbacks that we define?

For example, we use this function to explicitly encrypt the name and email field before insertion:

defp encrypt_fields(changeset) do
  case changeset.valid? do
    true ->
      {:ok, encrypted_email} = EncryptedField.dump(changeset.data.email)
      {:ok, encrypted_name} = EncryptedField.dump(changeset.data.name)
      changeset
      |> put_change(:email, encrypted_email)
      |> put_change(:name, encrypted_name)
    _ ->
      changeset
  end
end

From what I understand, both the email and name field are using our custom EncryptedField Ecto type, and therefore the dump callback defined in Encryption.EncryptedField will be called just before the data is inserted into the database, encrypting the field values before saving them.

Similarly, we're explictly calling EncryptedField.load on the retrieved value in User.one/0:

def one() do
    user =
      %User{name: name, email: email, key_id: key_id, password_hash: password_hash} =
      Repo.one(User)

    {:ok, email} = EncryptedField.load(email, key_id)
    {:ok, name} = EncryptedField.load(name, key_id)
    %{user | email: email, name: name, password_hash: password_hash}
 end

I guess we need this function so that we can explicitly specify the key_id, but doesn't that mean that we're encrypting the value twice before inserting it into the database (once implicitly, once explicitly), and decrypting it twice (once implicitly, once explicitly) when retrieving it?

Thanks again for putting this tutorial together!

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions