class Gibberish::AES
# Handles AES
encryption and decryption with some sensible defaults
- 256 bit AES encryption - GCM mode with Authentication - 100,000 iterations of PBKDF2_HMAC for key strengthening
## Compatibility with SJCL
It outputs into a format that is compatible with SJCL and easy to consume in browsers/Node.js
## Basic Usage
### Encrypting
cipher = Gibberish::AES.new('p4ssw0rd') cipher.encrypt("some secret text") #=> Outputs a JSON string containing all the necessary information
### Decrypting
cipher = Gibberish::AES.new('p4ssw0rd') cipher.decrypt('{"iv":"I4XKgNfMNkYhvzXc","v":1,"iter":1000,"ks":128,"ts":64,"mode":"gcm","adata":"123abc","cipher":"aes","salt":"PJsit8L16Ug=","ct":"5sEBsHXQqLXLOjxuVQK7fGZVdrMyRGDJ"}') #=> "some secret text"
#### Including Authenticated data.
GCM mode allows you to include “Authenticated Data” with the ciphertext, if you wish. For an overview of Authenticated Data, see this post: [crypto.stackexchange.com/a/15701](http://crypto.stackexchange.com/a/15701)
Using AD is easy with Gibberish
cipher = Gibberish::AES.new('p4ssw0rd') ciphertext = cipher.encrypt("Some secret data", "my authenticated data") plaintext = cipher.decrypt(ciphertext) #=> "some secret text" plaintext.adata # => "my authenticated data"
## Interoperability with SJCL's GCM mode AES
#### Decrypting
“`javascript // In the browser var cleartext = sjcl.decrypt('key', '[output from Gibberish
AES]'); “`
#### Encrypting
Ruby OpenSSL cannot handle an IV longer than 12 bytes, therefore we need to tell SJCL
to only use a 3 word IV value. See: github.com/bitwiseshiftleft/sjcl/issues/180
“`javascript // In the browser var ciphertext = sjcl.encrypt('key', 'plain text', {mode: 'gcm', iv: sjcl.random.randomWords(3, 0)}); “`
## Backward compatibility with older pre 2.0 Gibberish
Gibberish was previously designed to be compatible with OpenSSL on the command line with CBC mode AES. This has been deprecated in favor of GCM mode. However, you may still decrypt and encrypt using legacy convenience methods below: (Note: OpenSSL "enc" uses a non-standard file format which lacks [key stretching](http://en.wikipedia.org/wiki/Key_stretching), this means less secure passwords are more susceptible to brute forcing.)
### AES-256-CBC mode
cipher = Gibberish::AES::CBC.new('p4ssw0rd') cipher_text = cipher.encrypt("some secret text") # => U2FsdGVkX1/D7z2azGmmQELbMNJV/n9T/9j2iBPy2AM= cipher.decrypt(cipher_text) # From the command line echo "U2FsdGVkX1/D7z2azGmmQELbMNJV/n9T/9j2iBPy2AM=\n" | openssl enc -d -aes-256-cbc -a -k p4ssw0rd
Public Class Methods
Returns the AES
object
@param [String] password @param [Hash] opts @option opts [Symbol] :mode ('gcm') the AES
mode to use @option opts [Symbol] :ks (256) keystrength @option opts [Symbol] :iter (100_000) number of PBKDF2 iterations to run on the password @option opts [Symbol] :max_iter (100_000) maximum allow iterations, set to prevent DOS attack of someone setting a large 'iter' value in the ciphertext JSON @option opts [Symbol] :ts (64) length of the authentication data hash
# File lib/gibberish/aes.rb, line 91 def initialize(password, opts={}) @cipher = SJCL.new(password, opts) end
Public Instance Methods
Returns a Plaintext object (essentially a String with an additional 'adata' attribute)
@param [String] ciphertext
# File lib/gibberish/aes.rb, line 106 def decrypt(ciphertext) @cipher.decrypt(ciphertext) end
Returns the ciphertext in the form of a JSON string
@param [String] data @param [String] authenticated_data (Won't be encrypted)
# File lib/gibberish/aes.rb, line 99 def encrypt(data, authenticated_data='') @cipher.encrypt(data, authenticated_data) end