class EncryptedCredentials::Coder

Public Class Methods

decrypt(data_bin, key_hex) click to toggle source
# File lib/encrypted_credentials/coder.rb, line 12
def self.decrypt(data_bin, key_hex)
  encrypted_data, iv, auth_tag = data_bin.split("--").map { |v| Base64.strict_decode64(v) }
  key = [key_hex].pack('H*')

  cipher_type =
    case key.bytes.length
    when 16
      'aes-128-gcm'
    when 32
      'aes-256-gcm'
    else
      raise "Wrong key length: #{key.bytes.length}"
    end

  raise "Unauthenticated message" if auth_tag.nil? || auth_tag.bytes.length != 16

  cipher = OpenSSL::Cipher.new(cipher_type)
  cipher.decrypt
  cipher.key = key
  cipher.iv = iv
  cipher.auth_tag = auth_tag
  cipher.auth_data = ""

  decrypted_data = cipher.update(encrypted_data)
  decrypted_data << cipher.final

  if decrypted_data.bytes[0..1] == [4, 8]
    Marshal.load(decrypted_data)
  else
    decrypted_data
  end
end
encrypt(data_bin, key_hex, use_marshal = true) click to toggle source
# File lib/encrypted_credentials/coder.rb, line 59
def self.encrypt(data_bin, key_hex, use_marshal = true)
  key = [key_hex].pack('H*')

  cipher_type =
    case key.bytes.length
    when 16
      'aes-128-gcm'
    when 32
      'aes-256-gcm'
    else
      raise "Wrong key length: #{key.bytes.length}"
    end

  cipher = OpenSSL::Cipher.new(cipher_type)
  cipher.encrypt
  cipher.key = key
  iv = cipher.random_iv
  cipher.auth_data = ""

  data = data_bin
  data = Marshal.dump(data) if use_marshal
  encrypted_data = cipher.update(data)
  encrypted_data << cipher.final

  [encrypted_data, iv, cipher.auth_tag].map{ |x| Base64.strict_encode64(x) }.join('--')
end
generate_key_hex(cipher = 'aes-128-gcm') click to toggle source
# File lib/encrypted_credentials/coder.rb, line 45
def self.generate_key_hex(cipher = 'aes-128-gcm')
  key_length =
    case cipher
    when 'aes-128-gcm'
      16
    when 'aes-256-gcm'
      32
    else
      raise "Unsupported cipher: #{cipher}"
    end

  SecureRandom.hex(key_length)
end