Class: Ably::Util::Crypto

Inherits:
Object
  • Object
show all
Defined in:
lib/submodules/ably-ruby/lib/ably/util/crypto.rb

Constant Summary collapse

DEFAULTS =
{
  algorithm: 'AES',
  mode: 'CBC',
  key_length: 128,
}
BLOCK_LENGTH =
16

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options) ⇒ Ably::Util::Crypto

Creates a Ably::Util::Crypto object

Examples:

crypto = Ably::Util::Crypto.new(key: 'mysecret')
encrypted = crypto.encrypt('secret text')
crypto.decrypt(decrypted) # => 'secret text'

Parameters:

  • options (Hash)

    an options Hash used to configure the Crypto library

Options Hash (options):

  • :key (String)

    Required secret key used for encrypting and decrypting

  • :algorithm (String)

    optional (default AES), specify the encryption algorithm supported by OpenSSL::Cipher

  • :mode (String)

    optional (default CBC), specify the cipher mode supported by OpenSSL::Cipher

  • :key_length (Integer)

    optional (default 128), specify the key length of the cipher supported by OpenSSL::Cipher

  • :combined (String)

    optional (default AES-128-CBC), specify in one option the algorithm, key length and cipher of the cipher supported by OpenSSL::Cipher

Raises:

  • (ArgumentError)


35
36
37
38
# File 'lib/submodules/ably-ruby/lib/ably/util/crypto.rb', line 35

def initialize(options)
  raise ArgumentError, ':key is required' unless options.has_key?(:key)
  @options = DEFAULTS.merge(options).freeze
end

Instance Attribute Details

#optionsHash (readonly)

Configured options for this Crypto object, see #initialize for a list of configured options

Returns:

  • (Hash)


17
18
19
# File 'lib/submodules/ably-ruby/lib/ably/util/crypto.rb', line 17

def options
  @options
end

Instance Method Details

#cipher_typeString

The Cipher algorithm string such as AES-128-CBC

Returns:

  • (String)


92
93
94
# File 'lib/submodules/ably-ruby/lib/ably/util/crypto.rb', line 92

def cipher_type
  (options[:combined] || "#{options[:algorithm]}-#{options[:key_length]}-#{options[:mode]}").to_s.upcase
end

#decrypt(encrypted_payload_with_iv) ⇒ String

Decrypt payload using configured Cipher

Parameters:

  • encrypted_payload_with_iv (String)

    the encrypted payload to be decrypted

Returns:

  • (String)

Raises:



64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/submodules/ably-ruby/lib/ably/util/crypto.rb', line 64

def decrypt(encrypted_payload_with_iv)
  raise Ably::Exceptions::CipherError, 'iv is missing or not long enough' unless encrypted_payload_with_iv.length >= BLOCK_LENGTH*2

  iv = encrypted_payload_with_iv.slice(0...BLOCK_LENGTH)
  encrypted_payload = encrypted_payload_with_iv.slice(BLOCK_LENGTH..-1)

  decipher = openssl_cipher
  decipher.decrypt
  decipher.key = key
  decipher.iv = iv

  decipher.update(encrypted_payload) << decipher.final
end

#encrypt(payload, encrypt_options = {}) ⇒ String

Encrypt payload using configured Cipher

Parameters:

  • payload (String)

    the payload to be encrypted

  • encrypt_options (Hash) (defaults to: {})

    an options Hash to configure the encrypt action

Options Hash (encrypt_options):

  • :iv (String)

    optionally use the provided Initialization Vector instead of a randomly generated IV

Returns:

  • (String)

    binary string with Encoding::ASCII_8BIT encoding



48
49
50
51
52
53
54
55
56
# File 'lib/submodules/ably-ruby/lib/ably/util/crypto.rb', line 48

def encrypt(payload, encrypt_options = {})
  cipher = openssl_cipher
  cipher.encrypt
  cipher.key = key
  iv = encrypt_options[:iv] || options[:iv] || cipher.random_iv
  cipher.iv = iv

  iv << cipher.update(payload) << cipher.final
end

#random_ivString

Generate a random IV

Returns:

  • (String)


86
87
88
# File 'lib/submodules/ably-ruby/lib/ably/util/crypto.rb', line 86

def random_iv
  openssl_cipher.random_iv
end

#random_keyString

Generate a random key

Returns:

  • (String)


80
81
82
# File 'lib/submodules/ably-ruby/lib/ably/util/crypto.rb', line 80

def random_key
  openssl_cipher.random_key
end