class Envcrypt::Envcrypter

Attributes

key[R]

Public: Returns the key used to encrypt/decrypt secrets

Public Class Methods

new(key = ENV['ENVCRYPT_KEY']) click to toggle source

Public: Initialize an Envcrypter object

key - A string representing the key to be used for encryption

and decryption (default: ENV['ENVCRYPT_KEY'])
# File lib/envcrypt/envcrypt.rb, line 20
def initialize(key = ENV['ENVCRYPT_KEY'])
  @key = key == nil ? generate_key : key
  @de_cipher = nil
  @en_cipher = nil
end

Public Instance Methods

decrypt(encrypted) click to toggle source

Public: Decrypts a secret

secret - the encrypted string to be decrypted

Returns the plain text decrypted string

# File lib/envcrypt/envcrypt.rb, line 52
def decrypt(encrypted)
  cipher = create_cipher(:decrypt)
  plaintxt = cipher.update Base64.decode64(encrypted)
  plaintxt << cipher.final
end
encrypt(secret) click to toggle source

Public: Encrypts a secret

secret - the secret string to be encrypted

Returns the encrypted string

# File lib/envcrypt/envcrypt.rb, line 39
def encrypt(secret)
  cipher = create_cipher(:encrypt)

  encrypted = cipher.update secret
  encrypted << cipher.final
  Base64.encode64(encrypted).chomp
end
generate_key() click to toggle source

Public: Generates a random key

Returns the key

# File lib/envcrypt/envcrypt.rb, line 29
def generate_key
  @key = "#{SecureRandom.base64}$#{SecureRandom.base64(32)}$#{SecureRandom.base64}"
end

Private Instance Methods

create_cipher(mode) click to toggle source

Internal: Create an encryption cipher

mode - Set the mode to either :encrypt or :decrypt

Returns a cipher to be used for encryption or decryption

# File lib/envcrypt/envcrypt.rb, line 85
def create_cipher(mode)
  create_cipher_simple(mode)
end
create_cipher_pbkdf2(mode) click to toggle source

Future: Create a cipher using the more secure pbkdf2_mac method

This one is more secure but doesn’t work on Heroku Would like to optionally detect OpenSSL version and use this if possible

# File lib/envcrypt/envcrypt.rb, line 111
def create_cipher_pbkdf2(mode)
  iv,pwd,salt = parse_key(@key)

  cipher = OpenSSL::Cipher.new 'AES-128-CBC'
  cipher.send(mode)
  cipher.iv = iv

  digest = OpenSSL::Digest::SHA256.new
  key_len = cipher.key_len
  iter = 20000
  cipher.key = OpenSSL::PKCS5.pbkdf2_hmac(pwd, salt, iter, key_len, digest)
  cipher
end
create_cipher_simple(mode) click to toggle source

Internal: Create a simple encryption cipher

mode - Set the mode to either :encrypt or :decrypt

Returns a cipher to be used for encryption or decryption

# File lib/envcrypt/envcrypt.rb, line 94
def create_cipher_simple(mode)
  iv,pwd,salt = parse_key(@key)

  cipher = OpenSSL::Cipher.new 'AES-128-CBC'
  cipher.send(mode)

  cipher.iv = iv
  cipher.key = pwd
  cipher
end
parse_key(key) click to toggle source

Internal: Parses a key string into three components used by the encryption ciphers. The components are stored as private instance variables. Keeping it all in a single string simplifies storing the key in environment variables.

key - the key to be parsed

Returns the key parsed into three components (iv,pwd,salt)

# File lib/envcrypt/envcrypt.rb, line 70
def parse_key(key)
  parsed = key.split('$')
  if parsed.length != 3
    raise "Bad key format - generate a new one"
  else
    parsed
  end
end