Class: Ably::Util::Crypto

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

Overview

Contains the properties required to configure the encryption of Models::Message payloads.

Constant Summary collapse

DEFAULTS =
{
  algorithm: 'aes',
  mode: 'cbc',
  key_length: 256,
}
BLOCK_LENGTH =
16

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

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

Creates a Ably::Util::Crypto object

Examples:

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

Parameters:

Options Hash (params):

  • :key (String, Binary)

    Required private key must be either a binary (e.g. a ASCII_8BIT encoded string), or a base64-encoded string. If the key is a base64-encoded string, the it will be automatically converted into a binary

  • :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



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

def initialize(params)
  @fixed_iv = params[:fixed_iv]
  @cipher_params = Ably::Models::CipherParams(params)
end

Instance Attribute Details

#cipher_paramsAbly::Models::CipherParams (readonly)

Configured Models::CipherParams for this Crypto object, see #initialize for a list of configureable options



20
21
22
# File 'lib/submodules/ably-ruby/lib/ably/util/crypto.rb', line 20

def cipher_params
  @cipher_params
end

Class Method Details

.cipher_type(options) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

The Cipher algorithm string such as AES-128-CBC



68
69
70
# File 'lib/submodules/ably-ruby/lib/ably/util/crypto.rb', line 68

def self.cipher_type(options)
  Ably::Models::CipherParams.cipher_type(options)
end

.generate_random_key(key_length = DEFAULTS.fetch(:key_length)) ⇒ Object

Generates a random key to be used in the encryption of the channel. If the language cryptographic randomness primitives are blocking or async, a callback is used. The callback returns a generated binary key.

Parameters:

  • key_length (Integer) (defaults to: DEFAULTS.fetch(:key_length))

    The length of the key, in bits, to be generated. If not specified, this is equal to the default keyLength of the default algorithm: for AES this is 256 bits.

Returns:

  • Binary The key as a binary, for example, a byte array.



61
62
63
64
# File 'lib/submodules/ably-ruby/lib/ably/util/crypto.rb', line 61

def self.generate_random_key(key_length = DEFAULTS.fetch(:key_length))
  params = DEFAULTS.merge(key_length: key_length)
  OpenSSL::Cipher.new(cipher_type(params)).random_key
end

.get_default_params(params = {}) ⇒ Ably::Models::CipherParams

Returns a Models::CipherParams object, using the default values for any fields not supplied by the ‘Hash` object.

Parameters:

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

    a Hash used to configure the Crypto library’s Models::CipherParams

Returns:



49
50
51
# File 'lib/submodules/ably-ruby/lib/ably/util/crypto.rb', line 49

def self.get_default_params(params = {})
  Ably::Models::CipherParams(params)
end

Instance Method Details

#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:



96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/submodules/ably-ruby/lib/ably/util/crypto.rb', line 96

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



80
81
82
83
84
85
86
87
88
# File 'lib/submodules/ably-ruby/lib/ably/util/crypto.rb', line 80

def encrypt(payload, encrypt_options = {})
  cipher = openssl_cipher
  cipher.encrypt
  cipher.key = key
  iv = encrypt_options[:iv] || fixed_iv || cipher.random_iv
  cipher.iv = iv
  iv << cipher.update(payload) unless payload.empty?
  iv << cipher.final
end

#random_ivString

Generate a random IV

Returns:

  • (String)


112
113
114
# File 'lib/submodules/ably-ruby/lib/ably/util/crypto.rb', line 112

def random_iv
  openssl_cipher.random_iv
end