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]
SALT_CHARSET =

Printable ASCII chars go from 32 to 126

Array(32..126).map{ |i| i.chr }

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
# File 'lib/encrypted_text/codec.rb', line 16

def initialize(opts)
  config = {
    :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 (readonly)

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



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/encrypted_text/codec.rb', line 47

def decode(encoded)
  begin
    hex_string = Radix.convert(encoded, 62, 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(byte_string)
  rescue #TODO: don't use generic rescue here
    raise EncryptedText::Err::CannotDecrypt
  end

  # Ensure that the message is signed correctly
  raise EncryptedText::Err::BadSignature unless decrypted.index(@signature) == 0

  # Remove signature and salt
  decrypted[(@signature.size + @salt_size)..-1]
end

#encode(message) ⇒ Object



40
41
42
43
44
45
# File 'lib/encrypted_text/codec.rb', line 40

def encode(message)
  signed_and_salted = @signature + random_salt + message
  encrypted = @engine.encrypt(signed_and_salted)
  hex_string = '1' + encrypted.to_hex_string.split(' ').join # Add "1" prefix in case hex_string has leading zeroes
  encoded = Radix.convert(hex_string.upcase, 16, 62) # Radix requires allcaps
end

#random_saltObject



65
66
67
# File 'lib/encrypted_text/codec.rb', line 65

def random_salt
  (0...@salt_size).map{ SALT_CHARSET.sample }.join
end