encrypted_text 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.md CHANGED
@@ -1,12 +1,15 @@
1
1
  encrypted_text
2
2
  ==============
3
3
 
4
- Password-based, two-way encryption with string output. Uses AES encryption
4
+ Password-based, two-way encryption with string output. Uses AES encryption.
5
5
 
6
6
  Usage example
7
7
  -------------
8
8
 
9
- In order to encode or decode a message, you should know the **key** and **signature** ahead of time. The key is a 16-, 24-, or 32-character string used for AES encryption key. The signature is prepended to the message before encryption, and verified after decryption.
9
+ In order to encode or decode a message, you should know the **key** and **signature** ahead of time.
10
+
11
+ - The key is a 16-, 24-, or 32-character string, used as an AES encryption key.
12
+ - The signature is prepended to the message before encryption, and verified after decryption.
10
13
 
11
14
  ```ruby
12
15
  require 'encrypted_text'
@@ -20,7 +23,7 @@ encoded = codec.encode("Hello, world!")
20
23
  original_message = codec.decode(encoded)
21
24
  ```
22
25
 
23
- You can also add a random seed, so that repeated encodings of the same message produce different results.
26
+ You can also add a random salt, so that repeated encodings of the same message produce different results.
24
27
 
25
28
  ```ruby
26
29
  # Continued from previous example
@@ -34,6 +37,6 @@ b = codec.encode(message) # Should be a different result!
34
37
  Motivation
35
38
  ----------
36
39
 
37
- I wrote this library so I could generate tokens that encoded actual information, but seemed opaque and pseudo-random to the outside world.
40
+ Among other things, this library is useful for generating tokens that seem opaque to the outside world, but actually encode real information.
38
41
 
39
- In situations where tokens are passed from a service to an outside party and then back again, the service needs some way of resolving tokens passed back to it. Oftentimes this means performing a lookup on a stored mapping (e.g. a database query) between the token and some kind of cleartext data that outside parties never see. But this comes with all the clumsiness of maintaining and interacting with a persistent data store. For some applications, it might be acceptable simply to encode data directly into the token itself, using a secret that only the originating service has access to. EncryptedText provides a simple API to accomplish this.
42
+ For example, in situations where tokens are passed from a service to an outside party and then back again, the service needs some way of resolving tokens passed back to it. Oftentimes this means performing a lookup on a stored mapping (e.g. a database query) between the token and some kind of cleartext data that outside parties never see. But this comes with all the clumsiness of maintaining and interacting with a persistent data store. For some applications, it might be acceptable simply to encode data directly into the token itself, using a secret that only the originating service has access to. EncryptedText provides a simple API to accomplish this.
@@ -11,11 +11,10 @@ module EncryptedText
11
11
  attr_reader :charset, :key, :salt_size
12
12
 
13
13
  KEY_CHAR_SIZES = [16, 24, 32] # An AES key must be 8-bit char strings of these lengths
14
- DEFAULT_CHARSET = Array('A'..'Z') + Array('a'..'z') + Array('0'..'9') + [ '-', '_' ] # base 64, URL-safe
14
+ SALT_CHARSET = Array(32..126).map{ |i| i.chr } # Printable ASCII chars go from 32 to 126
15
15
 
16
16
  def initialize(opts)
17
17
  config = {
18
- :charset => DEFAULT_CHARSET,
19
18
  :signature => '',
20
19
  :key => nil,
21
20
  :salt_size => 0,
@@ -28,18 +27,9 @@ module EncryptedText
28
27
  end
29
28
  end
30
29
 
31
- def charset=(charset)
32
- @charset = charset
33
- @reverse_charset = @charset.each.with_index.reduce({}) do |res, (c, i)|
34
- res[c] = i
35
- res
36
- end
37
- end
38
-
39
30
  def key=(key)
31
+ @engine = FastAES.new(key)
40
32
  @key = key
41
- @engine = FastAES.new(@key)
42
- @key
43
33
  end
44
34
 
45
35
  def salt_size=(s)
@@ -47,18 +37,9 @@ module EncryptedText
47
37
  @salt_size = s
48
38
  end
49
39
 
50
- def base_encode(val, from_base)
51
- val.b(from_base).to_a.map{ |id| @charset[id] }.join
52
- end
53
-
54
- def base_decode(val)
55
- val.split.map{ |c| @reverse_charset.fetch(c) }.b(@charset.size).to_i
56
- end
57
-
58
40
  def encode(message)
59
- salt = (0...@salt_size).map { @charset.sample }.join
60
- signed = @signature + salt + message
61
- encrypted = @engine.encrypt(signed)
41
+ signed_and_salted = @signature + random_salt + message
42
+ encrypted = @engine.encrypt(signed_and_salted)
62
43
  hex_string = '1' + encrypted.to_hex_string.split(' ').join # Add "1" prefix in case hex_string has leading zeroes
63
44
  encoded = Radix.convert(hex_string.upcase, 16, 62) # Radix requires allcaps
64
45
  end
@@ -69,16 +50,20 @@ module EncryptedText
69
50
  hex_string = hex_string[1..-1] if hex_string[0] == '1' # remove "1" prefix
70
51
  hex_string = "0" + hex_string if (hex_string.size % 2) != 0 # Make sure we have an even number of hex digits
71
52
  byte_string = hex_string.to_byte_string
72
- decrypted = @engine.decrypt(hex_string.to_byte_string)
53
+ decrypted = @engine.decrypt(byte_string)
73
54
  rescue #TODO: don't use generic rescue here
74
55
  raise EncryptedText::Err::CannotDecrypt
75
56
  end
76
57
 
77
58
  # Ensure that the message is signed correctly
78
- matches = decrypted.match(/^#{Regexp.escape(signature)}(.+)/)
79
- raise EncryptedText::Err::BadSignature unless matches
80
- salted_message = matches[1]
81
- message = salted_message[@salt_size..-1]
59
+ raise EncryptedText::Err::BadSignature unless decrypted.index(@signature) == 0
60
+
61
+ # Remove signature and salt
62
+ decrypted[(@signature.size + @salt_size)..-1]
63
+ end
64
+
65
+ def random_salt
66
+ (0...@salt_size).map{ SALT_CHARSET.sample }.join
82
67
  end
83
68
 
84
69
  end
@@ -1,3 +1,3 @@
1
1
  module EncryptedText
2
- VERSION = '0.1.1'
2
+ VERSION = '0.1.2'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: encrypted_text
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-09-12 00:00:00.000000000 Z
12
+ date: 2012-09-13 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: fast-aes