Class: AionS3::Packer

Inherits:
Object
  • Object
show all
Defined in:
lib/aion_s3/packer.rb

Overview

A Packer is a utility for packing and unpacking data. Packing applies compression and encryption to provided data. Unpacking applies decryption and decompression to provided data.

Encryption uses cipher AES-256-CBC. The key is generated via a password provided when the Packer is initialized. The password must be a string at least 20 chars long.

It is very important that the password is randomly generated.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(password = nil) ⇒ Packer

Returns a new Packer object with a key based on the given password. If no password is provided, a random password will be generated The password can later be read via #password.

Parameters:

  • password (String) (defaults to: nil)


25
26
27
28
29
30
31
32
# File 'lib/aion_s3/packer.rb', line 25

def initialize(password = nil)
  password ||= Packer.random_password
  if password and password.size < 32
    raise ArgumentError, 'Provided password must be at least 32 characters'
  end
  @key = OpenSSL::Digest.digest('sha256', password)
  @password = password.freeze
end

Instance Attribute Details

#passwordString (readonly)

Returns:

  • (String)


18
19
20
# File 'lib/aion_s3/packer.rb', line 18

def password
  @password
end

Class Method Details

.random_password(n = 24) ⇒ String

Returns a base64 encoded string based on random bytes. The length will be n * 2 characters.

If n is not defined, it will default to 24, which will generate a 32 character base64 encoded string.

Parameters:

  • n (Integer) (defaults to: 24)

Returns:

  • (String)

    a base64 encoded string



115
116
117
# File 'lib/aion_s3/packer.rb', line 115

def self.random_password(n = 24)
  SecureRandom.base64(n)
end

Instance Method Details

#decrypt(data) ⇒ String

Decrypts data that have been encrypted using #encrypt(data) and returns it as a binary encoded string.

Parameters:

  • data (String)

Returns:

  • (String)

    a binary encoded string



49
50
51
52
53
54
55
# File 'lib/aion_s3/packer.rb', line 49

def decrypt(data)
  _data = data
  decipher = OpenSSL::Cipher::AES.new(256, :cbc).decrypt
  decipher.key = @key
  decipher.iv = _data.byteslice(0,16)
  decipher.update(_data.byteslice(16, _data.bytesize - 16)) + decipher.final
end

#deflate(data) ⇒ String

Decompresses data with zlib and returns it a binary encoded string.

Parameters:

  • data (String)

Returns:

  • (String)

    a binary encoded string



61
62
63
# File 'lib/aion_s3/packer.rb', line 61

def deflate(data)
  Zlib::Deflate.deflate(data, Zlib::BEST_COMPRESSION)
end

#encrypt(data) ⇒ String

Encrypts data with AES-256-CBC and returns it as a binary encoded string.

Parameters:

  • data (String)

Returns:

  • (String)

    a binary encoded string



38
39
40
41
42
43
# File 'lib/aion_s3/packer.rb', line 38

def encrypt(data)
  _data = data
  cipher = OpenSSL::Cipher::AES.new(256, :cbc).encrypt
  cipher.key = @key
  cipher.random_iv + cipher.update(_data) + cipher.final
end

#inflate(data) ⇒ String

Compresses data with zlib and returns it a binary encoded string.

Parameters:

  • data (String)

Returns:

  • (String)

    a binary encoded string



69
70
71
# File 'lib/aion_s3/packer.rb', line 69

def inflate(data)
  Zlib::Inflate.inflate(data)
end

#pack(data) ⇒ String

Compresses and encrypts given data.

Note The ruby string’s local encoding will be lost when packed. unpack(data) will always return a string with binary encoding.

Example:

data = 'æøå'  # utf8 encoded string
str = unpack(pack(data))

puts str.bytes == data.bytes
puts str == data
puts str.encoding == data.encoding

Produces:

true
false
false

Parameters:

  • data (String)

Returns:

  • (String)

    a binary encoded string



96
97
98
# File 'lib/aion_s3/packer.rb', line 96

def pack(data)
  encrypt(deflate(data))
end

#unpack(data) ⇒ String

Decrypts and decompresses given data.

Parameters:

  • data (Object)

Returns:

  • (String)

    a binary encoded string



104
105
106
# File 'lib/aion_s3/packer.rb', line 104

def unpack(data)
  inflate(decrypt(data))
end