dwyl / dwyl/phoenix-ecto-encryption-example

Explicit encryption required?

Open
#33 4 comments 4 reactions 0 assignees View on GitHub
good first issue help wanted question user-feedback
Dominant language
Elixir
Stars
291
Forks
21
Avg merge
1d 4h
Merged PRs (30d)
3

Description

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:

```elixir
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`:

```elixir
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!

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.