---
title: "Encryption Keys"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Encryption Keys}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)
```

```{r setup}
library(rmonocypher)
```

## Encryption Keys

An encryption key is the core secret data used to encrypt/decrypt an object.

Without knowing the encryption key, it is not possible to decrypt the data.

It is important to save this key securely.

Encryption keys must be 32 bytes of difficult to guess values, and the 
`{rmonocypher}` package has a number of ways of making keys easy to handle.

The `key` for encryption may be one of:

* A password
* A 32-byte raw vector
* A 64-character hexadecimal string


## Use a *password* as the key

When using `encrypt(..., key = ...)`, the key may simply be given as a *password*.
This password may be any text (including spaces and special characters).

Internally, this password will be processed into a full 32-byte encryption key
using **Argon2 password-based key derivation** (see below).

## Generate a key using Argon2 Key Derivation Function

An encryption `key` may be generated by a password prior to the call to `encrypt()`.

The `argon2()` function implements [Argon2 password-based key derivation](https://en.wikipedia.org/wiki/Argon2).
This is a resource intensive password-based key derivation scheme (i.e. requires lots 
of CPU and RAM to run) which is difficult to brute-force.

For applications requiring more paranoia, it is recommended that an 
explicit `salt` be used.  Don't forget to save the `salt` as well, because
without it you will not be able to generate the same encryption key.

```{r}
# When no salt is provided, a salt will be 
# derived internally from the password. 
argon2("my secret")
# Use another password as the salt
argon2("my secret", salt = "salt and vinegar")
# Use a 32-character hexadecimal string as the salt
argon2("my secret", salt = "cefca6aafae5bdbc15977fd56ea7f1eb")
# Use 'rbyte()' to source 16 random bytes for the salt
salt <- rbyte(16)
argon2("my secret", salt = salt)
```


## Setting a global key in `options()`

You may wish to load a pre-generated key at the start of a session and use this throughout.

If no `key` is provided, the `encrypt()` and `decrypt()` functions attempt to 
use a key stored in the named option: `MONOCYPHER_KEY`.

```{r eval=FALSE} 
# Create a key and set via options() 
key <- argon2("horse battery stapler")
options(MONOCYPHER_KEY = key)

encrypt(mydata, dst = "SharedDrive/mydata.rds")
decrypt(        src = "SharedDrive/mydata.rds")
```

## Use raw bytes as the key

The `key` may also be a raw vector containing 32 bytes.  

If using random bytes for the `key`, it is important that they be generated from a 
cryptographically secure source e.g. `rbyte()`.

Be sure to save this key, as it will not be possible to generate this 
exact same random sequence again.

```{r}
key <- rbyte(32, type = 'raw')
key
```

## Use hexadecimal string as a key

The `key` may be given as a 64-character hexadecimal string.

If this key is generated using `rbyte()`, be sure to save this key as it 
will not be possible to generate this exact same random sequence again.

```{r}
key <- rbyte(32, type = 'chr')
key
```

