Class: EncodedToken::Cipher

Inherits:
Object
  • Object
show all
Includes:
ErrorMessages
Defined in:
lib/encoded_token/cipher.rb

Overview

EncodedToken::Cipher

This class represents a cipher used by EncodedToken::Encryptor
for encryption.

Constant Summary collapse

CIPHER_COUNT =

======================================================================

Constants

======================================================================

16
CIPHER_CHARS =
(('0'..'9').to_a + ('a'..'z').to_a + ('A'..'Z').to_a).freeze
CIPHER_TEXT =
CIPHER_CHARS.join.freeze
CIPHER_INDEX_MAP =
CIPHER_TEXT.each_char.with_index.to_h.freeze
HEX_CHARS =
(('a'..'f').to_a + ('A'..'F').to_a).freeze
HEX_NUMS =
('0'..'9').to_a.freeze
SPECIAL_CHARS =
['-'].freeze
HEX_TEXT =
(HEX_NUMS + HEX_CHARS + SPECIAL_CHARS).join.freeze
HEX_INDEX_MAP =
HEX_TEXT.each_char.with_index.to_h.freeze
MAX_CIPHER_COUNT =
60

Constants included from ErrorMessages

ErrorMessages::CIPHER_ERRORS, ErrorMessages::CONFIG_ERRORS, ErrorMessages::ENCODED_TOKEN_ERRORS, ErrorMessages::ENCODER_ERRORS, ErrorMessages::ENCRYPTOR_ERRORS, ErrorMessages::ERROR_MESSAGES, ErrorMessages::V1_ENCODER_ERRORS

Instance Method Summary collapse

Constructor Details

#initialize(seed, expiry_date = nil, cipher_count = EncodedToken.configuration.cipher_count) ⇒ Cipher

Initializes a new Cipher instance.

Parameters:

  • seed (Integer)

    the seed for randomization.

  • expiry_date (Date, Time, nil) (defaults to: nil)

    the date when this cipher expires.

  • cipher_count (Integer) (defaults to: EncodedToken.configuration.cipher_count)

    the number of keys to generate.



47
48
49
50
51
52
53
# File 'lib/encoded_token/cipher.rb', line 47

def initialize(seed, expiry_date = nil, cipher_count = EncodedToken.configuration.cipher_count)
  @seed         = seed
  @expiry_date  = expiry_date
  @cipher_count = cipher_count

  build_cipher!
end

Instance Method Details

#cipher_countInteger

Returns the number of keys in the cipher.

Returns:

  • (Integer)


200
201
202
# File 'lib/encoded_token/cipher.rb', line 200

def cipher_count
  @cipher_count
end

#expired?Boolean

Checks if the cipher has expired.

Returns:

  • (Boolean)


191
192
193
# File 'lib/encoded_token/cipher.rb', line 191

def expired?
  @expiry_date ? Time.now > @expiry_date : false
end

#hex_mapHash<String, Integer>

Returns the index map for the hex text.

Returns:

  • (Hash<String, Integer>)


182
183
184
# File 'lib/encoded_token/cipher.rb', line 182

def hex_map
  HEX_INDEX_MAP
end

#hex_textString

Returns the hex text used for encryption mapping.

Returns:

  • (String)


173
174
175
# File 'lib/encoded_token/cipher.rb', line 173

def hex_text
  HEX_TEXT
end

#key_mapsHash<String, Hash>

Returns the map of keys to their respective index maps.

Returns:

  • (Hash<String, Hash>)


228
229
230
# File 'lib/encoded_token/cipher.rb', line 228

def key_maps
  @key_maps ||= {}
end

#key_paddingsHash<String, Integer>

Returns the map of keys to their respective padding sizes.

Returns:

  • (Hash<String, Integer>)


237
238
239
# File 'lib/encoded_token/cipher.rb', line 237

def key_paddings
  @key_paddings ||= {}
end

#key_textsHash<String, String>

Returns the map of keys to their respective cipher texts.

Returns:

  • (Hash<String, String>)


219
220
221
# File 'lib/encoded_token/cipher.rb', line 219

def key_texts
  @key_texts ||= {}
end

#keysArray<String>

Returns the list of keys.

Returns:

  • (Array<String>)


246
247
248
# File 'lib/encoded_token/cipher.rb', line 246

def keys
  @keys ||= []
end

#paddingInteger

Returns the padding size for the root key.

Returns:

  • (Integer)


164
165
166
# File 'lib/encoded_token/cipher.rb', line 164

def padding
  @key_paddings[@root_key]
end

#reset!nil

Resets the key rotation to the root key.

Returns:

  • (nil)


96
97
98
99
100
101
102
# File 'lib/encoded_token/cipher.rb', line 96

def reset!
  @rotation_key  = root_key
  @rotation_keys = keys.dup

  rotate_keys!(target_key: root_key)
  nil
end

#root_keyString

Returns a duplicate of the root key.

Returns:

  • (String)


69
70
71
# File 'lib/encoded_token/cipher.rb', line 69

def root_key
  @root_key.dup
end

#root_key=(new_key) ⇒ String

Sets the root key and resets the rotation.

Parameters:

  • new_key (String)

    the new root key.

Returns:

  • (String)

    the new root key.

Raises:

  • (ArgumentError)

    if the key is invalid.



85
86
87
88
89
# File 'lib/encoded_token/cipher.rb', line 85

def root_key=(new_key)
  fail_with(:invalid_root_key) unless valid_key?(new_key)
  @root_key = new_key
  reset!
end

#rotate_keys!(target_key: nil) ⇒ String

Rotates the current key.

Parameters:

  • target_key (String, nil) (defaults to: nil)

    the key to rotate to.

Returns:

  • (String)

    the new current rotation key.

Raises:

  • (ArgumentError)

    if the target key is invalid.



116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/encoded_token/cipher.rb', line 116

def rotate_keys!(target_key: nil)
  if target_key
    # noinspection RubyMismatchedArgumentType
    unless valid_key?(target_key)
      fail_with(:invalid_root_key)
    end
    rotation_keys.rotate! until rotation_keys.first == target_key
  else
    rotation_keys.rotate!
  end

  @rotation_key = rotation_keys.first
end

#rotation_keyString

Returns the current rotation key.

Returns:

  • (String)


210
211
212
# File 'lib/encoded_token/cipher.rb', line 210

def rotation_key
  @rotation_key
end

#rotation_keysArray<String>

Returns the list of keys in their current rotation order.

Returns:

  • (Array<String>)


255
256
257
# File 'lib/encoded_token/cipher.rb', line 255

def rotation_keys
  @rotation_keys ||= []
end

#seedInteger

Returns the seed used for this cipher.

Returns:

  • (Integer)


60
61
62
# File 'lib/encoded_token/cipher.rb', line 60

def seed
  @seed
end

#textString

Returns the cipher text for the current rotation key.

Returns:

  • (String)


146
147
148
# File 'lib/encoded_token/cipher.rb', line 146

def text
  key_texts[@rotation_key]
end

#text_mapHash<String, Integer>

Returns the index map for the current rotation key.

Returns:

  • (Hash<String, Integer>)


155
156
157
# File 'lib/encoded_token/cipher.rb', line 155

def text_map
  key_maps[@rotation_key]
end

#valid_key?(key) ⇒ Boolean

Checks if the given key is valid for this cipher.

Parameters:

  • key (String)

Returns:

  • (Boolean)


137
138
139
# File 'lib/encoded_token/cipher.rb', line 137

def valid_key?(key)
  keys.include?(key)
end