Class: Origami::Encryption::AES

Inherits:
Object
  • Object
show all
Defined in:
lib/origami/encryption.rb

Overview

Class wrapper for AES mode CBC.

Constant Summary collapse

BLOCKSIZE =
16

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(key, iv, use_padding = true) ⇒ AES

Returns a new instance of AES.



632
633
634
635
636
637
638
639
640
641
642
643
644
# File 'lib/origami/encryption.rb', line 632

def initialize(key, iv, use_padding = true)
  unless [16, 24, 32].include?(key.size)
    raise EncryptionError, "Key must have a length of 128, 192 or 256 bits."
  end

  if !iv.nil? && (iv.size != BLOCKSIZE)
    raise EncryptionError, "Initialization vector must have a length of #{BLOCKSIZE} bytes."
  end

  @key = key
  @iv = iv
  @use_padding = use_padding
end

Instance Attribute Details

#iv=(value) ⇒ Object (writeonly)

Sets the attribute iv

Parameters:

  • value

    the value to set the attribute iv to.



622
623
624
# File 'lib/origami/encryption.rb', line 622

def iv=(value)
  @iv = value
end

Class Method Details

.decrypt(key, data) ⇒ Object



628
629
630
# File 'lib/origami/encryption.rb', line 628

def self.decrypt(key, data)
  AES.new(key, nil).decrypt(data)
end

.encrypt(key, iv, data) ⇒ Object



624
625
626
# File 'lib/origami/encryption.rb', line 624

def self.encrypt(key, iv, data)
  AES.new(key, iv).encrypt(data)
end

Instance Method Details

#decrypt(data) ⇒ Object



664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
# File 'lib/origami/encryption.rb', line 664

def decrypt(data)
  unless data.size % BLOCKSIZE == 0
    raise EncryptionError, "Data must be 16-bytes padded (data size = #{data.size} bytes)"
  end

  @iv = data.slice!(0, BLOCKSIZE)

  aes = OpenSSL::Cipher.new("aes-#{@key.length << 3}-cbc").decrypt
  aes.iv = @iv
  aes.key = @key
  aes.padding = 0

  plain = (aes.update(data) + aes.final).unpack("C*")

  if @use_padding
    padlen = plain[-1]
    unless padlen.between?(1, 16)
      raise EncryptionError, "Incorrect padding length : #{padlen}"
    end

    padlen.times do
      pad = plain.pop
      raise EncryptionError, "Incorrect padding byte : 0x#{pad.to_s 16}" if pad != padlen
    end
  end

  plain.pack("C*")
end

#encrypt(data) ⇒ Object



646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
# File 'lib/origami/encryption.rb', line 646

def encrypt(data)
  if @iv.nil?
    raise EncryptionError, "No initialization vector has been set."
  end

  if @use_padding
    padlen = BLOCKSIZE - (data.size % BLOCKSIZE)
    data << (padlen.chr * padlen)
  end

  aes = OpenSSL::Cipher.new("aes-#{@key.length << 3}-cbc").encrypt
  aes.iv = @iv
  aes.key = @key
  aes.padding = 0

  @iv + aes.update(data) + aes.final
end