README.md in lockbox-0.4.6 vs README.md in lockbox-0.4.7
- old
+ new
@@ -188,10 +188,12 @@
end
```
## Action Text
+**Note:** Action Text uses direct uploads for files, which cannot be encrypted with application-level encryption like Lockbox. This only encrypts the database field.
+
Create a migration with:
```ruby
class AddBodyCiphertextToRichTexts < ActiveRecord::Migration[6.0]
def change
@@ -262,12 +264,13 @@
end
```
There are a few limitations to be aware of:
-- Metadata like image width and height are not extracted when encrypted
-- Direct uploads cannot be encrypted
+- Variants and previews aren’t supported when encrypted
+- Metadata like image width and height aren’t extracted when encrypted
+- Direct uploads can’t be encrypted with application-level encryption like Lockbox, but can use server-side encryption
To serve encrypted files, use a controller action.
```ruby
def license
@@ -506,10 +509,28 @@
Lockbox.rotate(User, attributes: [:email])
```
Once all records are rotated, you can remove `previous_versions` from the model.
+### Action Text
+
+Update your initializer:
+
+```ruby
+Lockbox.encrypts_action_text_body(previous_versions: [{key: previous_key}])
+```
+
+Use `master_key` instead of `key` if passing the master key.
+
+To rotate existing records, use:
+
+```ruby
+Lockbox.rotate(ActionText::RichText, attributes: [:body])
+```
+
+Once all records are rotated, you can remove `previous_versions` from the initializer.
+
### Active Storage
Update your model:
```ruby
@@ -548,10 +569,18 @@
User.find_each do |user|
user.license.rotate_encryption!
end
```
+For multiple files, use:
+
+```ruby
+User.find_each do |user|
+ user.licenses.map(&:rotate_encryption!)
+end
+```
+
Once all files are rotated, you can remove `previous_versions` from the model.
### Local Files & Strings
For local files and strings, use:
@@ -732,16 +761,36 @@
## Key Management
You can use a key management service to manage your keys with [KMS Encrypted](https://github.com/ankane/kms_encrypted).
+For Active Record and Mongoid, use:
+
```ruby
class User < ApplicationRecord
encrypts :email, key: :kms_key
end
```
+For Action Text, use:
+
+```ruby
+ActiveSupport.on_load(:action_text_rich_text) do
+ ActionText::RichText.has_kms_key
+end
+
+Lockbox.encrypts_action_text_body(key: :kms_key)
+```
+
+For Active Storage, use:
+
+```ruby
+class User < ApplicationRecord
+ encrypts_attached :license, key: :kms_key
+end
+```
+
For CarrierWave, use:
```ruby
class LicenseUploader < CarrierWave::Uploader::Base
encrypt key: -> { model.kms_key }
@@ -770,11 +819,11 @@
lockbox.encrypt("fail").bytesize # 44
lockbox.encrypt("clear").bytesize # 44
lockbox.encrypt("consider").bytesize # 44
```
-The block size for padding is 16 bytes by default. If we have a status larger than 15 bytes, it will have a different length than the others.
+The block size for padding is 16 bytes by default. Lockbox uses [ISO/IEC 7816-4](https://en.wikipedia.org/wiki/Padding_(cryptography)#ISO/IEC_7816-4) padding, which uses at least one byte, so if we have a status larger than 15 bytes, it will have a different length than the others.
```ruby
box.encrypt("length15status!").bytesize # 44
box.encrypt("length16status!!").bytesize # 60
```
@@ -783,22 +832,38 @@
```ruby
Lockbox.new(padding: 32) # bytes
```
+## Associated Data
+
+You can pass extra context during encryption to make sure encrypted data isn’t moved to a different context.
+
+```ruby
+lockbox = Lockbox.new(key: key)
+ciphertext = lockbox.encrypt(message, associated_data: "somecontext")
+```
+
+Without the same context, decryption will fail.
+
+```ruby
+lockbox.decrypt(ciphertext, associated_data: "somecontext") # success
+lockbox.decrypt(ciphertext, associated_data: "othercontext") # fails
+```
+
## Binary Columns
-You can use `binary` columns for the ciphertext instead of `text` columns to save space.
+You can use `binary` columns for the ciphertext instead of `text` columns.
```ruby
class AddEmailCiphertextToUsers < ActiveRecord::Migration[6.0]
def change
add_column :users, :email_ciphertext, :binary
end
end
```
-You should disable Base64 encoding if you do this.
+Disable Base64 encoding to save space.
```ruby
class User < ApplicationRecord
encrypts :email, encode: false
end