README.md in cryptor-0.0.2 vs README.md in cryptor-1.0.0
- old
+ new
@@ -18,11 +18,12 @@
XSalsa20+Poly1305 from [libsodium].
* [ActiveSupport::MessageEncryptor]: (Rails 4+) a bespoke authenticated
encryption scheme provided by Rails, based on AES-CBC and HMAC.
Cryptor uses the experimental [ORDO v0 message format][ordo] for serializing
-encrypted messages.
+encrypted messages. Future versions may support additional message formats
+like OpenPGP or JWE.
[authenticated encryption]: https://en.wikipedia.org/wiki/Authenticated_encryption
[RbNaCl::SimpleBox]: https://github.com/cryptosphere/rbnacl/wiki/SimpleBox
[libsodium]: https://github.com/jedisct1/libsodium/
[ActiveSupport::MessageEncryptor]: http://api.rubyonrails.org/classes/ActiveSupport/MessageEncryptor.html
@@ -46,11 +47,11 @@
To begin with, you must select a backend:
### RbNaCl (recommended)
-RbNaCl is a Ruby FFI binding to libsodium, a portable state-of-the-art
+[RbNaCl] is a Ruby FFI binding to libsodium, a portable state-of-the-art
cryptography library.
To use Cryptor with RbNaCl, add the following to your Gemfile:
```ruby
@@ -59,12 +60,13 @@
And in your Ruby program, require the following:
```ruby
require 'cryptor'
-require 'cryptor/ciphers/xsalsa20poly1305'
+require 'cryptor/symmetric_encryption/ciphers/xsalsa20poly1305'
```
+[RbNaCl]: https://github.com/cryptosphere/rbnacl/
### Rails (ActiveSupport::MessageEncryptor)
Cryptor can use ActiveSupport 4.0+'s `MessageEncryptor` class to encrypt
messages. This scheme uses AES-256 in CBC mode for encryption and HMAC-SHA1
@@ -77,11 +79,11 @@
To use Cryptor with ActiveSupport::MessageEncryptor, require the following
from a Rails 4.0+ app or other app with ActiveSupport 4.0+ bundled:
```ruby
require 'cryptor'
-require 'cryptor/ciphers/message_encryptor'
+require 'cryptor/symmetric_encryption/ciphers/message_encryptor'
```
### Authenticated Symmetric Encryption
To encrypt data with Cryptor, you must first make a secret key to encrypt it
@@ -111,11 +113,12 @@
key's [ORDO secret URI].
To obtain the secret URI, use the `#to_secret_uri` method, which returns a string:
```ruby
-"secret.key:///xsalsa20poly1305;0saB1tfgKWDh_bX0oAquLWgAq-6yjG1u04mP-CtQG-4"
+>> secret_key.to_secret_uri
+=> "secret.key:///xsalsa20poly1305;0saB1tfgKWDh_bX0oAquLWgAq-6yjG1u04mP-CtQG-4"
```
This string can be saved somewhere secret and safe then later loaded and passed into
`Cryptor::SymmetricEncryption.new`:
@@ -135,9 +138,42 @@
decrypted = cryptor.decrypt(ciphertext)
```
[RFC 6920]: http://tools.ietf.org/html/rfc6920
[ORDO secret URI]: https://github.com/cryptosphere/ordo/wiki/URI-Registry
+
+## Key Rotation
+
+Cryptor is designed to support key rotation, allowing new ciphertexts to be
+produced under an "active" key, but with old keys configured so older
+ciphertexts can still be decrypted (and also rotated to the new key).
+
+To rotate keys, first make a new key, but configure Cryptor with the old key
+too using the "keyring" option:
+
+```ruby
+old_key = ...
+new_key = Cryptor::SymmetricEncryption.random_key(:xsalsa20poly1305)
+cryptor = Cryptor::SymmetricEncryption.new(new_key, keyring: [old_key])
+```
+
+Cryptor can support arbitrarily many old keys on its keyring. Any messages
+which have been encrypted under the old keys can still be decrypted, but
+newly encrypted messages will always use the new "active" key.
+
+To rotate messages from one key to another, use the `#rotate` method:
+
+```ruby
+old_message = ...
+new_message = cryptor.rotate(old_message)
+```
+
+This is useful if a key is ever compromised, and also good security hygene
+in general.
+
+Cryptor also supports the `#rotate!` method, which works just like `#rotate`,
+but raises `Cryptor::AlreadyRotatedError` if asked to rotate a message that's
+already up-to-date.
## Contributing
* Fork this repository on Github
* Make your changes and send a pull request