Class: Ably::Util::Crypto

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

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


32
33
34
35
# File 'lib/ably/util/crypto.rb', line 32

def initialize(params)
  @fixed_iv = params.delete(:fixed_iv) if params.kind_of?(Hash)
  @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


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

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


64
65
66
# File 'lib/ably/util/crypto.rb', line 64

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

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

Generate a random encryption key from the supplied keylength (or the default key_length of 256 if none supplied)

Parameters:

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

    Optional (default 256) key length for the generated random key. 128 and 256 bit key lengths are supported

Returns:

  • Binary String (byte array) with ASCII_8BIT encoding


57
58
59
60
# File 'lib/ably/util/crypto.rb', line 57

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 Configured cipher params with :key, :algorithm, :mode, :key_length attributes

Parameters:

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

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

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

Returns:


47
48
49
# File 'lib/ably/util/crypto.rb', line 47

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:


92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/ably/util/crypto.rb', line 92

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


76
77
78
79
80
81
82
83
84
# File 'lib/ably/util/crypto.rb', line 76

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) << cipher.final
end

#random_ivString

Generate a random IV

Returns:

  • (String)

108
109
110
# File 'lib/ably/util/crypto.rb', line 108

def random_iv
  openssl_cipher.random_iv
end