module Garcon::Crypto
Crypto
uses the AES-256-CBC algorithm by default to encrypt strings securely. It uses both an initialization vector (IV) and a salt to perform this encryption as securely as possible.
@example
Use `#encrypt` to encrypt a string. text = "what is 42?" salt = "9e5f851900cad8892ac8b737b7370cbe" pass = "!mWh0!s@y!m" encrypted_text = Crypto.encrypt(text, set_password, set_salt) # => "+opVpqJhQsD3dbOQ8GAGjmq7slIms2zCQmOrMxJGpqQ=\n" Then to decrypt the string use `#decrypt`. Crypto.decrypt(encrypted_text, pass, salt) # => "what is 42?" You can also set the salt and password on a configuration object. Garcon::Crypto.config do |config| config.password = "!mWh0!s@y!m" config.salt = "9e5f851900cad8892ac8b737b7370cbe" end Now you can #encrypt and #decrypt without specifying a salt and password. encrypted_text = Crypto.encrypt(text) # => "HQRabUG8BcS+yZR8yG9TqQWfFPFYXztRgoQjdAUseFU=\n" Crypto.decrypt(encrypted_text) # => "what is 42?" What you probably want to use this for is directly on a String. encrypted_text = text.encrypt # => "ew2SEyf+09WdPJHRjmBGp4g6C1oSQaDbQiZ/7WEceEc=\n" encrypted_text.decrypt # => "what is 42?"
@note
The salt needs to be unique per-use per-encrypted string. Every time a string is encrypted, it should be hashed using a new random salt. Never reuse a salt. The salt also needs to be long, so that there are many possible salts. As a rule of thumb, the salt should be at least 32 random bytes. Garcon includes a easy helper for you to generate a random binary string, `String.random_binary(SIZE)`, where size is the size in bytes.
Constants
- CIPHER_TYPE
- CRYPTERATIONS
- HASH_BYTE_SIZE
- SALT_BYTE_SIZE
The default size, iterations and cipher encryption algorithm used.
Public Instance Methods
Decrypt the given string, using the salt and password supplied.
@param [String] encrypted_text
The text to decrypt, probably produced with #decrypt.
@param [String] password
Secret passphrase to decrypt with.
@param [String] salt
The cryptographically secure pseudo-random string used to spice up the encryption of your strings.
@return [String]
The decrypted plain_text.
@api public
# File lib/garcon/utility/crypto.rb, line 180 def decrypt(encrypted_text, password = nil, salt = nil) password = password.nil? ? Garcon.crypto.password : password salt = salt.nil? ? Garcon.crypto.salt : salt iv_ciphertext = Base64.decode64(encrypted_text) cipher = new_cipher(:decrypt, password, salt) cipher.iv, ciphertext = separate_iv_ciphertext(cipher, iv_ciphertext) plain_text = cipher.update(ciphertext) plain_text << cipher.final plain_text end
Encrypt the given string using the AES-256-CBC algorithm.
@param [String] plain_text
The text to encrypt.
@param [String] password
Secret passphrase to encrypt with.
@param [String] salt
A cryptographically secure pseudo-random string (SecureRandom.base64) to add a little spice to your encryption.
@return [String]
Encrypted text, can be deciphered with #decrypt.
@api public
# File lib/garcon/utility/crypto.rb, line 153 def encrypt(plain_text, password = nil, salt = nil) password = password.nil? ? Garcon.crypto.password : password salt = salt.nil? ? Garcon.crypto.salt : salt cipher = new_cipher(:encrypt, password, salt) cipher.iv = iv = cipher.random_iv ciphertext = cipher.update(plain_text) ciphertext << cipher.final Base64.encode64(combine_iv_ciphertext(iv, ciphertext)) end
Generates a special hash known as a SPASH, a PBKDF2-HMAC-SHA1 Salted Password Hash
for safekeeping.
@param [String] password
A password to generating the SPASH, salted password hash.
@return [Hash]
`:salt` contains the unique salt used, `:pbkdf2` contains the password hash. Save both the salt and the hash together.
@see Garcon::Crypto#validate_salt
@api public
# File lib/garcon/utility/crypto.rb, line 205 def salted_hash(password) salt = SecureRandom.random_bytes(SALT_BYTE_SIZE) pbkdf2 = OpenSSL::PKCS5::pbkdf2_hmac_sha1( password, salt, CRYPTERATIONS, HASH_BYTE_SIZE ) { salt: salt, pbkdf2: Base64.encode64(pbkdf2) } end