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.


581
582
583
584
585
586
587
588
589
590
591
592
593
# File 'lib/origami/encryption.rb', line 581

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 not iv.nil? and 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.


571
572
573
# File 'lib/origami/encryption.rb', line 571

def iv=(value)
  @iv = value
end

Class Method Details

.decrypt(key, data) ⇒ Object


577
578
579
# File 'lib/origami/encryption.rb', line 577

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

.encrypt(key, iv, data) ⇒ Object


573
574
575
# File 'lib/origami/encryption.rb', line 573

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

Instance Method Details

#decrypt(data) ⇒ Object


613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
# File 'lib/origami/encryption.rb', line 613

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 (1..16) === padlen
            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


595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
# File 'lib/origami/encryption.rb', line 595

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