Class: EncryptedText::Codec

Inherits:
Object
  • Object
show all
Defined in:
lib/encrypted_text/codec.rb

Constant Summary collapse

KEY_CHAR_SIZES =

An AES key must be 8-bit char strings of these lengths

[16, 24, 32]
DEFAULT_CHARSET =

base 64, URL-safe

Array('A'..'Z') + Array('a'..'z') + Array('0'..'9') + [ '-', '_' ]

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opts) ⇒ Codec

Returns a new instance of Codec.



16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/encrypted_text/codec.rb', line 16

def initialize(opts)
  config = {
    :charset => DEFAULT_CHARSET,
    :signature => '',
    :key => nil,
    :salt_size => 0,
  }

  config.keys.each do |k|
    # Replace default value with argument
    v = opts.has_key?(k) ? opts[k] : config[k]
    self.send "#{k}=", v
  end
end

Instance Attribute Details

#charsetObject

Returns the value of attribute charset.



11
12
13
# File 'lib/encrypted_text/codec.rb', line 11

def charset
  @charset
end

#keyObject

Returns the value of attribute key.



11
12
13
# File 'lib/encrypted_text/codec.rb', line 11

def key
  @key
end

#salt_sizeObject

Returns the value of attribute salt_size.



11
12
13
# File 'lib/encrypted_text/codec.rb', line 11

def salt_size
  @salt_size
end

#signatureObject

Returns the value of attribute signature.



10
11
12
# File 'lib/encrypted_text/codec.rb', line 10

def signature
  @signature
end

Instance Method Details

#decode(encoded) ⇒ Object



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/encrypted_text/codec.rb', line 59

def decode(encoded)
  begin
    hex_string = @base_converter.convert_to_base_10(encoded).to_base_16
    hex_string = hex_string[1..-1] if hex_string[0] == '1' # remove "1" prefix
    hex_string = "0" + hex_string if (hex_string.size % 2) != 0 # Make sure we have an even number of hex digits
    byte_string = hex_string.to_byte_string
    decrypted = @engine.decrypt(hex_string.to_byte_string)
  rescue #TODO: don't use generic rescue here
    raise EncryptedText::Err::CannotDecrypt
  end

  # Ensure that the message is signed correctly
  matches = decrypted.match(/^#{Regexp.escape(signature)}(.+)/)
  raise EncryptedText::Err::BadSignature unless matches
  salted_message = matches[1]
  message = salted_message[@salt_size..-1]
end

#encode(message) ⇒ Object



50
51
52
53
54
55
56
57
# File 'lib/encrypted_text/codec.rb', line 50

def encode(message)
  salt = (0...@salt_size).map { @charset.sample }.join
  signed = @signature + salt + message
  encrypted = @engine.encrypt(signed)
  hex_string = encrypted.to_hex_string.split(' ').join
  hex = ("1" + hex_string).hex # Add "1" prefix in case hex_string has leading zeroes
  encoded = @base_converter.convert_from_base_10(hex.to_i)
end