class Cryptor::SymmetricEncryption

Easy-to-use authenticated symmetric encryption

Public Class Methods

new(active_key, options = {}) click to toggle source
# File lib/cryptor/symmetric_encryption.rb, line 15
def initialize(active_key, options = {})
  @active_key = active_key.is_a?(SecretKey) ? active_key : SecretKey.new(active_key)
  @keyring    = nil

  options.each do |name, value|
    if name == :keyring
      @keyring = Keyring.new(@active_key, *value)
    else fail ArgumentError, "unknown option: #{name}"
    end
  end

  @keyring ||= Keyring.new(active_key)
end
random_key(cipher) click to toggle source
# File lib/cryptor/symmetric_encryption.rb, line 11
def self.random_key(cipher)
  Cipher[cipher].random_key
end

Public Instance Methods

decrypt(ciphertext) click to toggle source
# File lib/cryptor/symmetric_encryption.rb, line 42
def decrypt(ciphertext)
  message = parse(ciphertext)
  fingerprint = message['Key-Fingerprint']
  fail InvalidMessageError, 'no key fingerprint in message' unless fingerprint

  key = @keyring[fingerprint]
  key.decrypt message.body
end
encrypt(plaintext) click to toggle source
# File lib/cryptor/symmetric_encryption.rb, line 29
def encrypt(plaintext)
  ciphertext = @active_key.encrypt(plaintext)
  base64     = Base64.strict_encode64(ciphertext)

  ORDO::Message.new(
    base64,
    'Cipher'                    => @active_key.cipher.algorithm,
    'Content-Length'            => base64.bytesize,
    'Content-Transfer-Encoding' => 'base64',
    'Key-Fingerprint'           => @active_key.fingerprint
  ).to_string
end
rotate(ciphertext) click to toggle source
# File lib/cryptor/symmetric_encryption.rb, line 60
def rotate(ciphertext)
  rotate!(ciphertext)
rescue AlreadyRotatedError
  ciphertext
end
rotate!(ciphertext) click to toggle source
# File lib/cryptor/symmetric_encryption.rb, line 51
def rotate!(ciphertext)
  message = parse(ciphertext)
  fingerprint = message['Key-Fingerprint']
  fail AlreadyRotatedError, 'already current' if fingerprint == @active_key.fingerprint

  key = @keyring[fingerprint]
  encrypt(key.decrypt(message.body))
end

Private Instance Methods

parse(message) click to toggle source
# File lib/cryptor/symmetric_encryption.rb, line 68
def parse(message)
  ORDO::Message.parse(message)
rescue ORDO::ParseError => ex
  raise InvalidMessageError, ex.to_s
end