encryptor 1.1.3 → 1.3.0

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.
@@ -0,0 +1,121 @@
1
+ ## Encryptor [![Build Status](https://travis-ci.org/attr-encrypted/encryptor.png?branch=master)](https://travis-ci.org/attr-encrypted/encryptor)
2
+
3
+ A simple wrapper for the standard Ruby OpenSSL library
4
+
5
+ Intended to be used by a future version of `http://github.com/shuber/attr_encrypted` to easily encrypt/decrypt attributes in any Ruby class or model.
6
+
7
+ ### Installation
8
+
9
+ ```bash
10
+ gem install encryptor
11
+ ```
12
+
13
+ ### Usage
14
+
15
+ #### Basic
16
+
17
+ Encryptor uses the AES-256-CBC algorithm by default to encrypt strings securely. You are strongly advised to use both an initialization vector (via the `:iv` option) and a salt (via the `:salt` option) to perform this encryption as securely as possible. Specifying only an `:iv` option without `:salt` is not recommended but is supported as part of a "compatibility mode" to support clients built using older versions of this gem.
18
+
19
+ The best example is:
20
+
21
+ ```ruby
22
+ salt = Time.now.to_i.to_s
23
+ secret_key = 'secret'
24
+ iv = OpenSSL::Cipher::Cipher.new('aes-256-cbc').random_iv
25
+ encrypted_value = Encryptor.encrypt('some string to encrypt', :key => secret_key, :iv => iv, :salt => salt)
26
+ decrypted_value = Encryptor.decrypt(encrypted_value, :key => secret_key, :iv => iv, :salt => salt)
27
+ ```
28
+
29
+ The value to encrypt or decrypt may also be passed as the :value option if you'd prefer.
30
+
31
+ ```ruby
32
+ encrypted_value = Encryptor.encrypt(:value => 'some string to encrypt', :key => secret_key, :iv => iv, :salt => salt)
33
+ decrypted_value = Encryptor.decrypt(:value => encrypted_value, :key => secret_key, :iv => iv, :salt => salt)
34
+ ```
35
+
36
+ **You may also skip the salt and the IV if you like. Do so at your own risk!**
37
+
38
+ ```ruby
39
+ encrypted_value = Encryptor.encrypt(:value => 'some string to encrypt', :key => 'secret')
40
+ decrypted_value = Encryptor.decrypt(:value => encrypted_value, :key => 'secret')
41
+ ```
42
+
43
+ You may also pass an `:algorithm` option, though this is not required.
44
+
45
+ ```ruby
46
+ Encryptor.default_options.merge!(:algorithm => 'aes-128-cbc', :key => 'some default secret key', :iv => iv, :salt => salt)
47
+ ```
48
+
49
+ #### Strings
50
+
51
+ Encryptor adds `encrypt` and `decrypt` methods to `String` objects for your convenience. These two methods accept the same arguments as the associated ones in the `Encryptor` module. They're nice when you set the default options in the `Encryptor.default_options attribute.` For example:
52
+
53
+ ```ruby
54
+ Encryptor.default_options.merge!(:key => 'some default secret key', :iv => iv, :salt => salt)
55
+ credit_card = 'xxxx xxxx xxxx 1234'
56
+ encrypted_credit_card = credit_card.encrypt
57
+ ```
58
+
59
+ There's also `encrypt!` and `decrypt!` methods that replace the contents of a string with the encrypted or decrypted version of itself.
60
+
61
+ ### Algorithms
62
+
63
+ Run `openssl list-cipher-commands` in your terminal to view a list of all cipher algorithms that are supported on your platform. Typically, this will include the following:
64
+
65
+ aes-128-cbc
66
+ aes-128-ecb
67
+ aes-192-cbc
68
+ aes-192-ecb
69
+ aes-256-cbc
70
+ aes-256-ecb
71
+ bf
72
+ bf-cbc
73
+ bf-cfb
74
+ bf-ecb
75
+ bf-ofb
76
+ cast
77
+ cast-cbc
78
+ cast5-cbc
79
+ cast5-cfb
80
+ cast5-ecb
81
+ cast5-ofb
82
+ des
83
+ des-cbc
84
+ des-cfb
85
+ des-ecb
86
+ des-ede
87
+ des-ede-cbc
88
+ des-ede-cfb
89
+ des-ede-ofb
90
+ des-ede3
91
+ des-ede3-cbc
92
+ des-ede3-cfb
93
+ des-ede3-ofb
94
+ des-ofb
95
+ des3
96
+ desx
97
+ idea
98
+ idea-cbc
99
+ idea-cfb
100
+ idea-ecb
101
+ idea-ofb
102
+ rc2
103
+ rc2-40-cbc
104
+ rc2-64-cbc
105
+ rc2-cbc
106
+ rc2-cfb
107
+ rc2-ecb
108
+ rc2-ofb
109
+ rc4
110
+ rc4-40
111
+
112
+ Note that some ciphers may not be supported by Ruby.
113
+
114
+ ### Notes on patches/pull requests
115
+
116
+ * Fork the project.
117
+ * Make your feature addition or bug fix.
118
+ * Add tests for it: this is important so I don't break it in a future version unintentionally.
119
+ * Commit, do not mess with Rakefile, version, or history: if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull).
120
+ * Send me a pull request: bonus points for topic branches.
121
+
data/Rakefile CHANGED
@@ -2,9 +2,6 @@ require 'rake'
2
2
  require 'rake/testtask'
3
3
  require 'rake/rdoctask'
4
4
 
5
- desc 'Default: run unit tests'
6
- task :default => :test
7
-
8
5
  desc 'Test the encryptor gem'
9
6
  Rake::TestTask.new(:test) do |t|
10
7
  t.libs << 'lib'
@@ -19,4 +16,18 @@ Rake::RDocTask.new(:rdoc) do |rdoc|
19
16
  rdoc.options << '--line-numbers' << '--inline-source'
20
17
  rdoc.rdoc_files.include('README*')
21
18
  rdoc.rdoc_files.include('lib/**/*.rb')
22
- end
19
+ end
20
+
21
+ if RUBY_VERSION < '1.9.3'
22
+ require 'rcov/rcovtask'
23
+
24
+ task :rcov do
25
+ system "rcov -o coverage/rcov --exclude '^(?!lib)' " + FileList[ 'test/**/*_test.rb' ].join(' ')
26
+ end
27
+
28
+ desc 'Default: run unit tests under rcov.'
29
+ task :default => :rcov
30
+ else
31
+ desc 'Default: run unit tests.'
32
+ task :default => :test
33
+ end
@@ -52,8 +52,19 @@ module Encryptor
52
52
  cipher = OpenSSL::Cipher::Cipher.new(options[:algorithm])
53
53
  cipher.send(cipher_method)
54
54
  if options[:iv]
55
- cipher.key = options[:key]
56
55
  cipher.iv = options[:iv]
56
+ if options[:salt].nil?
57
+ # Use a non-salted cipher.
58
+ # This behaviour is retained for backwards compatibility. This mode
59
+ # is not secure and new deployments should use the :salt options
60
+ # wherever possible.
61
+ cipher.key = options[:key]
62
+ else
63
+ # Use an explicit salt (which can be persisted into a database on a
64
+ # per-column basis, for example). This is the preferred (and more
65
+ # secure) mode of operation.
66
+ cipher.key = OpenSSL::PKCS5.pbkdf2_hmac_sha1(options[:key], options[:salt], 2000, cipher.key_len)
67
+ end
57
68
  else
58
69
  cipher.pkcs5_keyivgen(options[:key])
59
70
  end
@@ -61,4 +72,4 @@ module Encryptor
61
72
  result = cipher.update(options[:value])
62
73
  result << cipher.final
63
74
  end
64
- end
75
+ end
@@ -2,8 +2,8 @@ module Encryptor
2
2
  # Contains information about this gem's version
3
3
  module Version
4
4
  MAJOR = 1
5
- MINOR = 1
6
- PATCH = 3
5
+ MINOR = 3
6
+ PATCH = 0
7
7
 
8
8
  # Returns a version string by joining <tt>MAJOR</tt>, <tt>MINOR</tt>, and <tt>PATCH</tt> with <tt>'.'</tt>
9
9
  #
@@ -14,4 +14,4 @@ module Encryptor
14
14
  [MAJOR, MINOR, PATCH].join('.')
15
15
  end
16
16
  end
17
- end
17
+ end
@@ -0,0 +1,93 @@
1
+ require File.expand_path('../test_helper', __FILE__)
2
+
3
+ # Test ensures that values stored by previous versions of the gem will
4
+ # roundtrip and decrypt correctly in this and future versions. This is important
5
+ # for data stored in databases and allows consumers of the gem to upgrade with
6
+ # confidence in the future.
7
+ #
8
+ class CompatibilityTest < Test::Unit::TestCase
9
+ ALGORITHM = 'aes-256-cbc'
10
+
11
+ def self.base64_encode(value)
12
+ [value].pack('m').strip
13
+ end
14
+
15
+ def self.base64_decode(value)
16
+ value.unpack('m').first
17
+ end
18
+
19
+ if OpenSSL::Cipher.ciphers.include?(ALGORITHM)
20
+ def test_encrypt_with_iv
21
+ key = Digest::SHA256.hexdigest('my-fixed-key')
22
+ iv = Digest::SHA256.hexdigest('my-fixed-iv')
23
+ result = Encryptor.encrypt(
24
+ :algorithm => ALGORITHM,
25
+ :value => 'my-fixed-input',
26
+ :key => key,
27
+ :iv => iv
28
+ )
29
+ assert_equal 'nGuyGniksFXnMYj/eCxXKQ==', self.class.base64_encode(result)
30
+ end
31
+
32
+ def test_encrypt_without_iv
33
+ key = Digest::SHA256.hexdigest('my-fixed-key')
34
+ result = Encryptor.encrypt(
35
+ :algorithm => ALGORITHM,
36
+ :value => 'my-fixed-input',
37
+ :key => key
38
+ )
39
+ assert_equal 'XbwHRMFWqR5M80kgwRcEEg==', self.class.base64_encode(result)
40
+ end
41
+
42
+ def test_decrypt_with_iv
43
+ key = Digest::SHA256.hexdigest('my-fixed-key')
44
+ iv = Digest::SHA256.hexdigest('my-fixed-iv')
45
+ result = Encryptor.decrypt(
46
+ :algorithm => ALGORITHM,
47
+ :value => self.class.base64_decode('nGuyGniksFXnMYj/eCxXKQ=='),
48
+ :key => key,
49
+ :iv => iv
50
+ )
51
+ assert_equal 'my-fixed-input', result
52
+ end
53
+
54
+ def test_decrypt_without_iv
55
+ key = Digest::SHA256.hexdigest('my-fixed-key')
56
+ result = Encryptor.decrypt(
57
+ :algorithm => ALGORITHM,
58
+ :value => self.class.base64_decode('XbwHRMFWqR5M80kgwRcEEg=='),
59
+ :key => key
60
+ )
61
+ assert_equal 'my-fixed-input', result
62
+ end
63
+
64
+ def test_encrypt_with_iv_and_salt
65
+ key = Digest::SHA256.hexdigest('my-fixed-key')
66
+ iv = Digest::SHA256.hexdigest('my-fixed-iv')
67
+ salt = 'my-fixed-salt'
68
+ result = Encryptor.encrypt(
69
+ :algorithm => ALGORITHM,
70
+ :value => 'my-fixed-input',
71
+ :key => key,
72
+ :iv => iv,
73
+ :salt => salt
74
+ )
75
+ assert_equal 'DENuQSh9b0eW8GN3YLzLGw==', self.class.base64_encode(result)
76
+ end
77
+
78
+ def test_decrypt_with_iv_and_salt
79
+ key = Digest::SHA256.hexdigest('my-fixed-key')
80
+ iv = Digest::SHA256.hexdigest('my-fixed-iv')
81
+ salt = 'my-fixed-salt'
82
+ result = Encryptor.decrypt(
83
+ :algorithm => ALGORITHM,
84
+ :value => self.class.base64_decode('DENuQSh9b0eW8GN3YLzLGw=='),
85
+ :key => key,
86
+ :iv => iv,
87
+ :salt => salt
88
+ )
89
+ assert_equal 'my-fixed-input', result
90
+ end
91
+ end
92
+ end
93
+
@@ -1,20 +1,23 @@
1
1
  require File.expand_path('../test_helper', __FILE__)
2
+ require File.expand_path('../openssl_helper', __FILE__)
2
3
 
4
+ # Tests for new preferred salted encryption mode
5
+ #
3
6
  class EncryptorTest < Test::Unit::TestCase
4
7
 
5
- algorithms = %x(openssl list-cipher-commands).split
6
8
  key = Digest::SHA256.hexdigest(([Time.now.to_s] * rand(3)).join)
7
9
  iv = Digest::SHA256.hexdigest(([Time.now.to_s] * rand(3)).join)
10
+ salt = Time.now.to_i.to_s
8
11
  original_value = Digest::SHA256.hexdigest(([Time.now.to_s] * rand(3)).join)
9
12
 
10
- algorithms.reject { |algorithm| algorithm == 'base64' }.each do |algorithm|
11
- encrypted_value_with_iv = Encryptor.encrypt(:value => original_value, :key => key, :iv => iv, :algorithm => algorithm)
13
+ OpenSSLHelper::ALGORITHMS.each do |algorithm|
14
+ encrypted_value_with_iv = Encryptor.encrypt(:value => original_value, :key => key, :iv => iv, :salt => salt, :algorithm => algorithm)
12
15
  encrypted_value_without_iv = Encryptor.encrypt(:value => original_value, :key => key, :algorithm => algorithm)
13
16
 
14
17
  define_method "test_should_crypt_with_the_#{algorithm}_algorithm_with_iv" do
15
18
  assert_not_equal original_value, encrypted_value_with_iv
16
19
  assert_not_equal encrypted_value_without_iv, encrypted_value_with_iv
17
- assert_equal original_value, Encryptor.decrypt(:value => encrypted_value_with_iv, :key => key, :iv => iv, :algorithm => algorithm)
20
+ assert_equal original_value, Encryptor.decrypt(:value => encrypted_value_with_iv, :key => key, :iv => iv, :salt => salt, :algorithm => algorithm)
18
21
  end
19
22
 
20
23
  define_method "test_should_crypt_with_the_#{algorithm}_algorithm_without_iv" do
@@ -23,7 +26,7 @@ class EncryptorTest < Test::Unit::TestCase
23
26
  end
24
27
 
25
28
  define_method "test_should_encrypt_with_the_#{algorithm}_algorithm_with_iv_with_the_first_arg_as_the_value" do
26
- assert_equal encrypted_value_with_iv, Encryptor.encrypt(original_value, :key => key, :iv => iv, :algorithm => algorithm)
29
+ assert_equal encrypted_value_with_iv, Encryptor.encrypt(original_value, :key => key, :iv => iv, :salt => salt, :algorithm => algorithm)
27
30
  end
28
31
 
29
32
  define_method "test_should_encrypt_with_the_#{algorithm}_algorithm_without_iv_with_the_first_arg_as_the_value" do
@@ -31,7 +34,7 @@ class EncryptorTest < Test::Unit::TestCase
31
34
  end
32
35
 
33
36
  define_method "test_should_decrypt_with_the_#{algorithm}_algorithm_with_iv_with_the_first_arg_as_the_value" do
34
- assert_equal original_value, Encryptor.decrypt(encrypted_value_with_iv, :key => key, :iv => iv, :algorithm => algorithm)
37
+ assert_equal original_value, Encryptor.decrypt(encrypted_value_with_iv, :key => key, :iv => iv, :salt => salt, :algorithm => algorithm)
35
38
  end
36
39
 
37
40
  define_method "test_should_decrypt_with_the_#{algorithm}_algorithm_without_iv_with_the_first_arg_as_the_value" do
@@ -39,7 +42,7 @@ class EncryptorTest < Test::Unit::TestCase
39
42
  end
40
43
 
41
44
  define_method "test_should_call_encrypt_on_a_string_with_the_#{algorithm}_algorithm_with_iv" do
42
- assert_equal encrypted_value_with_iv, original_value.encrypt(:key => key, :iv => iv, :algorithm => algorithm)
45
+ assert_equal encrypted_value_with_iv, original_value.encrypt(:key => key, :iv => iv, :salt => salt, :algorithm => algorithm)
43
46
  end
44
47
 
45
48
  define_method "test_should_call_encrypt_on_a_string_with_the_#{algorithm}_algorithm_without_iv" do
@@ -47,7 +50,7 @@ class EncryptorTest < Test::Unit::TestCase
47
50
  end
48
51
 
49
52
  define_method "test_should_call_decrypt_on_a_string_with_the_#{algorithm}_algorithm_with_iv" do
50
- assert_equal original_value, encrypted_value_with_iv.decrypt(:key => key, :iv => iv, :algorithm => algorithm)
53
+ assert_equal original_value, encrypted_value_with_iv.decrypt(:key => key, :iv => iv, :salt => salt, :algorithm => algorithm)
51
54
  end
52
55
 
53
56
  define_method "test_should_call_decrypt_on_a_string_with_the_#{algorithm}_algorithm_without_iv" do
@@ -56,8 +59,8 @@ class EncryptorTest < Test::Unit::TestCase
56
59
 
57
60
  define_method "test_string_encrypt!_on_a_string_with_the_#{algorithm}_algorithm_with_iv" do
58
61
  original_value_dup = original_value.dup
59
- original_value_dup.encrypt!(:key => key, :iv => iv, :algorithm => algorithm)
60
- assert_equal original_value.encrypt(:key => key, :iv => iv, :algorithm => algorithm), original_value_dup
62
+ original_value_dup.encrypt!(:key => key, :iv => iv, :salt => salt, :algorithm => algorithm)
63
+ assert_equal original_value.encrypt(:key => key, :iv => iv, :salt => salt, :algorithm => algorithm), original_value_dup
61
64
  end
62
65
 
63
66
  define_method "test_string_encrypt!_on_a_string_with_the_#{algorithm}_algorithm_without_iv" do
@@ -68,7 +71,7 @@ class EncryptorTest < Test::Unit::TestCase
68
71
 
69
72
  define_method "test_string_decrypt!_on_a_string_with_the_#{algorithm}_algorithm_with_iv" do
70
73
  encrypted_value_with_iv_dup = encrypted_value_with_iv.dup
71
- encrypted_value_with_iv_dup.decrypt!(:key => key, :iv => iv, :algorithm => algorithm)
74
+ encrypted_value_with_iv_dup.decrypt!(:key => key, :iv => iv, :salt => salt, :algorithm => algorithm)
72
75
  assert_equal original_value, encrypted_value_with_iv_dup
73
76
  end
74
77
 
@@ -101,4 +104,5 @@ class EncryptorTest < Test::Unit::TestCase
101
104
  assert called
102
105
  end
103
106
 
104
- end
107
+ end
108
+
@@ -0,0 +1,107 @@
1
+ require File.expand_path('../test_helper', __FILE__)
2
+ require File.expand_path('../openssl_helper', __FILE__)
3
+
4
+ # Tests for legacy (non-salted) encryption mode
5
+ #
6
+ class LegacyEncryptorTest < Test::Unit::TestCase
7
+
8
+ key = Digest::SHA256.hexdigest(([Time.now.to_s] * rand(3)).join)
9
+ iv = Digest::SHA256.hexdigest(([Time.now.to_s] * rand(3)).join)
10
+ original_value = Digest::SHA256.hexdigest(([Time.now.to_s] * rand(3)).join)
11
+
12
+ OpenSSLHelper::ALGORITHMS.each do |algorithm|
13
+ encrypted_value_with_iv = Encryptor.encrypt(:value => original_value, :key => key, :iv => iv, :algorithm => algorithm)
14
+ encrypted_value_without_iv = Encryptor.encrypt(:value => original_value, :key => key, :algorithm => algorithm)
15
+
16
+ define_method "test_should_crypt_with_the_#{algorithm}_algorithm_with_iv" do
17
+ assert_not_equal original_value, encrypted_value_with_iv
18
+ assert_not_equal encrypted_value_without_iv, encrypted_value_with_iv
19
+ assert_equal original_value, Encryptor.decrypt(:value => encrypted_value_with_iv, :key => key, :iv => iv, :algorithm => algorithm)
20
+ end
21
+
22
+ define_method "test_should_crypt_with_the_#{algorithm}_algorithm_without_iv" do
23
+ assert_not_equal original_value, encrypted_value_without_iv
24
+ assert_equal original_value, Encryptor.decrypt(:value => encrypted_value_without_iv, :key => key, :algorithm => algorithm)
25
+ end
26
+
27
+ define_method "test_should_encrypt_with_the_#{algorithm}_algorithm_with_iv_with_the_first_arg_as_the_value" do
28
+ assert_equal encrypted_value_with_iv, Encryptor.encrypt(original_value, :key => key, :iv => iv, :algorithm => algorithm)
29
+ end
30
+
31
+ define_method "test_should_encrypt_with_the_#{algorithm}_algorithm_without_iv_with_the_first_arg_as_the_value" do
32
+ assert_equal encrypted_value_without_iv, Encryptor.encrypt(original_value, :key => key, :algorithm => algorithm)
33
+ end
34
+
35
+ define_method "test_should_decrypt_with_the_#{algorithm}_algorithm_with_iv_with_the_first_arg_as_the_value" do
36
+ assert_equal original_value, Encryptor.decrypt(encrypted_value_with_iv, :key => key, :iv => iv, :algorithm => algorithm)
37
+ end
38
+
39
+ define_method "test_should_decrypt_with_the_#{algorithm}_algorithm_without_iv_with_the_first_arg_as_the_value" do
40
+ assert_equal original_value, Encryptor.decrypt(encrypted_value_without_iv, :key => key, :algorithm => algorithm)
41
+ end
42
+
43
+ define_method "test_should_call_encrypt_on_a_string_with_the_#{algorithm}_algorithm_with_iv" do
44
+ assert_equal encrypted_value_with_iv, original_value.encrypt(:key => key, :iv => iv, :algorithm => algorithm)
45
+ end
46
+
47
+ define_method "test_should_call_encrypt_on_a_string_with_the_#{algorithm}_algorithm_without_iv" do
48
+ assert_equal encrypted_value_without_iv, original_value.encrypt(:key => key, :algorithm => algorithm)
49
+ end
50
+
51
+ define_method "test_should_call_decrypt_on_a_string_with_the_#{algorithm}_algorithm_with_iv" do
52
+ assert_equal original_value, encrypted_value_with_iv.decrypt(:key => key, :iv => iv, :algorithm => algorithm)
53
+ end
54
+
55
+ define_method "test_should_call_decrypt_on_a_string_with_the_#{algorithm}_algorithm_without_iv" do
56
+ assert_equal original_value, encrypted_value_without_iv.decrypt(:key => key, :algorithm => algorithm)
57
+ end
58
+
59
+ define_method "test_string_encrypt!_on_a_string_with_the_#{algorithm}_algorithm_with_iv" do
60
+ original_value_dup = original_value.dup
61
+ original_value_dup.encrypt!(:key => key, :iv => iv, :algorithm => algorithm)
62
+ assert_equal original_value.encrypt(:key => key, :iv => iv, :algorithm => algorithm), original_value_dup
63
+ end
64
+
65
+ define_method "test_string_encrypt!_on_a_string_with_the_#{algorithm}_algorithm_without_iv" do
66
+ original_value_dup = original_value.dup
67
+ original_value_dup.encrypt!(:key => key, :algorithm => algorithm)
68
+ assert_equal original_value.encrypt(:key => key, :algorithm => algorithm), original_value_dup
69
+ end
70
+
71
+ define_method "test_string_decrypt!_on_a_string_with_the_#{algorithm}_algorithm_with_iv" do
72
+ encrypted_value_with_iv_dup = encrypted_value_with_iv.dup
73
+ encrypted_value_with_iv_dup.decrypt!(:key => key, :iv => iv, :algorithm => algorithm)
74
+ assert_equal original_value, encrypted_value_with_iv_dup
75
+ end
76
+
77
+ define_method "test_string_decrypt!_on_a_string_with_the_#{algorithm}_algorithm_without_iv" do
78
+ encrypted_value_without_iv_dup = encrypted_value_without_iv.dup
79
+ encrypted_value_without_iv_dup.decrypt!(:key => key, :algorithm => algorithm)
80
+ assert_equal original_value, encrypted_value_without_iv_dup
81
+ end
82
+ end
83
+
84
+ define_method 'test_should_use_the_default_algorithm_if_one_is_not_specified' do
85
+ assert_equal Encryptor.encrypt(:value => original_value, :key => key, :algorithm => Encryptor.default_options[:algorithm]), Encryptor.encrypt(:value => original_value, :key => key)
86
+ end
87
+
88
+ def test_should_have_a_default_algorithm
89
+ assert !Encryptor.default_options[:algorithm].nil?
90
+ assert !Encryptor.default_options[:algorithm].empty?
91
+ end
92
+
93
+ def test_should_raise_argument_error_if_key_is_not_specified
94
+ assert_raises(ArgumentError) { Encryptor.encrypt('some value') }
95
+ assert_raises(ArgumentError) { Encryptor.decrypt('some encrypted string') }
96
+ assert_raises(ArgumentError) { Encryptor.encrypt('some value', :key => '') }
97
+ assert_raises(ArgumentError) { Encryptor.decrypt('some encrypted string', :key => '') }
98
+ end
99
+
100
+ def test_should_yield_block_with_cipher_and_options
101
+ called = false
102
+ Encryptor.encrypt('some value', :key => 'some key') { |cipher, options| called = true }
103
+ assert called
104
+ end
105
+
106
+ end
107
+
@@ -0,0 +1,6 @@
1
+ require File.expand_path('../test_helper', __FILE__)
2
+
3
+ module OpenSSLHelper
4
+ ALGORITHMS = %x(openssl list-cipher-commands).split & OpenSSL::Cipher.ciphers
5
+ end
6
+
@@ -1,3 +1,17 @@
1
+ if RUBY_VERSION >= '1.9.3'
2
+ require 'simplecov'
3
+ require 'simplecov-rcov'
4
+
5
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
6
+ SimpleCov::Formatter::HTMLFormatter,
7
+ SimpleCov::Formatter::RcovFormatter,
8
+ ]
9
+
10
+ SimpleCov.start do
11
+ add_filter 'test'
12
+ end
13
+ end
14
+
1
15
  require 'test/unit'
2
16
  require 'digest/sha2'
3
17
 
metadata CHANGED
@@ -1,75 +1,120 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: encryptor
3
- version: !ruby/object:Gem::Version
4
- hash: 21
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.3.0
5
5
  prerelease:
6
- segments:
7
- - 1
8
- - 1
9
- - 3
10
- version: 1.1.3
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Sean Huber
9
+ - S. Brent Faulkner
10
+ - William Monk
14
11
  autorequire:
15
12
  bindir: bin
16
13
  cert_chain: []
17
-
18
- date: 2011-04-12 00:00:00 -07:00
19
- default_executable:
20
- dependencies: []
21
-
22
- description: A simple wrapper for the standard ruby OpenSSL library to encrypt and decrypt strings
23
- email: shuber@huberry.com
14
+ date: 2013-11-14 00:00:00.000000000 Z
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: rake
18
+ requirement: !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - '='
22
+ - !ruby/object:Gem::Version
23
+ version: 0.9.2.2
24
+ type: :development
25
+ prerelease: false
26
+ version_requirements: !ruby/object:Gem::Requirement
27
+ none: false
28
+ requirements:
29
+ - - '='
30
+ - !ruby/object:Gem::Version
31
+ version: 0.9.2.2
32
+ - !ruby/object:Gem::Dependency
33
+ name: simplecov
34
+ requirement: !ruby/object:Gem::Requirement
35
+ none: false
36
+ requirements:
37
+ - - ! '>='
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ type: :development
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ none: false
44
+ requirements:
45
+ - - ! '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ - !ruby/object:Gem::Dependency
49
+ name: simplecov-rcov
50
+ requirement: !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ type: :development
57
+ prerelease: false
58
+ version_requirements: !ruby/object:Gem::Requirement
59
+ none: false
60
+ requirements:
61
+ - - ! '>='
62
+ - !ruby/object:Gem::Version
63
+ version: '0'
64
+ description: A simple wrapper for the standard ruby OpenSSL library to encrypt and
65
+ decrypt strings
66
+ email:
67
+ - shuber@huberry.com
68
+ - sbfaulkner@gmail.com
69
+ - billy.monk@gmail.com
24
70
  executables: []
25
-
26
71
  extensions: []
27
-
28
72
  extra_rdoc_files: []
29
-
30
- files:
73
+ files:
31
74
  - lib/encryptor/string.rb
32
75
  - lib/encryptor/version.rb
33
76
  - lib/encryptor.rb
34
77
  - MIT-LICENSE
35
78
  - Rakefile
36
- - README.rdoc
79
+ - README.md
80
+ - test/compatibility_test.rb
37
81
  - test/encryptor_test.rb
82
+ - test/legacy_encryptor_test.rb
83
+ - test/openssl_helper.rb
38
84
  - test/test_helper.rb
39
- has_rdoc: true
40
- homepage: http://github.com/shuber/encryptor
85
+ homepage: http://github.com/attr-encrypted/encryptor
41
86
  licenses: []
42
-
43
87
  post_install_message:
44
88
  rdoc_options: []
45
-
46
- require_paths:
89
+ require_paths:
47
90
  - lib
48
- required_ruby_version: !ruby/object:Gem::Requirement
91
+ required_ruby_version: !ruby/object:Gem::Requirement
49
92
  none: false
50
- requirements:
51
- - - ">="
52
- - !ruby/object:Gem::Version
53
- hash: 3
54
- segments:
93
+ requirements:
94
+ - - ! '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ segments:
55
98
  - 0
56
- version: "0"
57
- required_rubygems_version: !ruby/object:Gem::Requirement
99
+ hash: -1331952118017536783
100
+ required_rubygems_version: !ruby/object:Gem::Requirement
58
101
  none: false
59
- requirements:
60
- - - ">="
61
- - !ruby/object:Gem::Version
62
- hash: 3
63
- segments:
102
+ requirements:
103
+ - - ! '>='
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
106
+ segments:
64
107
  - 0
65
- version: "0"
108
+ hash: -1331952118017536783
66
109
  requirements: []
67
-
68
110
  rubyforge_project:
69
- rubygems_version: 1.6.2
111
+ rubygems_version: 1.8.23
70
112
  signing_key:
71
113
  specification_version: 3
72
114
  summary: A simple wrapper for the standard ruby OpenSSL library
73
- test_files:
115
+ test_files:
116
+ - test/compatibility_test.rb
74
117
  - test/encryptor_test.rb
118
+ - test/legacy_encryptor_test.rb
119
+ - test/openssl_helper.rb
75
120
  - test/test_helper.rb
@@ -1,103 +0,0 @@
1
- = Encryptor
2
-
3
- A simple wrapper for the standard ruby OpenSSL library
4
-
5
- Used by http://github.com/shuber/attr_encrypted to easily encrypt/decrypt attributes in any class
6
-
7
-
8
- == Installation
9
-
10
- gem install encryptor
11
-
12
-
13
- == Usage
14
-
15
-
16
- === Basic
17
-
18
- secret_key = Digest::SHA256.hexdigest('a secret key')
19
- encrypted_value = Encryptor.encrypt('some string to encrypt', :key => secret_key) # '������{)��q�ށ�ܣ��q���Au/�ޜP'
20
- decrypted_value = Encryptor.decrypt(encrypted_value, :key => secret_key) # 'some string to encrypt'
21
-
22
- The value to encrypt or decrypt may also be passed as the <tt>:value</tt> option if you'd like.
23
-
24
- encrypted_value = Encryptor.encrypt(:value => 'some string to encrypt', :key => secret_key) # '������{)��q�ށ�ܣ��q���Au/�ޜP'
25
- decrypted_value = Encryptor.decrypt(:value => encrypted_value, :key => secret_key) # 'some string to encrypt'
26
-
27
- You may also pass the <tt>:iv</tt> and <tt>:algorithm</tt> options but they are not required. If an algorithm is not specified, the Encryptor uses
28
- the algorithm found at <tt>Encryptor.default_options[:algorithm]</tt> which is <tt>aes-256-cbc</tt> by default. You can change the default options
29
- by overwriting or merging this attribute:
30
-
31
- Encryptor.default_options.merge!(:algorithm => 'bf', :key => 'some default secret key')
32
-
33
-
34
- === Strings
35
-
36
- <tt>Encryptor</tt> adds <tt>encrypt</tt> and <tt>decrypt</tt> methods to <tt>String</tt> objects for your convenience. These two methods accept the same arguments as the associated ones in the <tt>Encryptor</tt> module. They're nice when you set the default options in the <tt>Encryptor.default_options</tt> attribute. For example:
37
-
38
- Encryptor.default_options.merge!(:key => 'some default secret key')
39
- credit_card = 'xxxx xxxx xxxx 1234'
40
- encrypted_credit_card = credit_card.encrypt
41
-
42
- There's also <tt>encrypt!</tt> and <tt>decrypt!</tt> methods that replace the contents of a string with the encrypted or decrypted version of itself.
43
-
44
-
45
- === Algorithms
46
-
47
- Run <tt>openssl list-cipher-commands</tt> in your terminal to view a list of all cipher algorithms that are supported on your platform.
48
-
49
- aes-128-cbc
50
- aes-128-ecb
51
- aes-192-cbc
52
- aes-192-ecb
53
- aes-256-cbc
54
- aes-256-ecb
55
- bf
56
- bf-cbc
57
- bf-cfb
58
- bf-ecb
59
- bf-ofb
60
- cast
61
- cast-cbc
62
- cast5-cbc
63
- cast5-cfb
64
- cast5-ecb
65
- cast5-ofb
66
- des
67
- des-cbc
68
- des-cfb
69
- des-ecb
70
- des-ede
71
- des-ede-cbc
72
- des-ede-cfb
73
- des-ede-ofb
74
- des-ede3
75
- des-ede3-cbc
76
- des-ede3-cfb
77
- des-ede3-ofb
78
- des-ofb
79
- des3
80
- desx
81
- idea
82
- idea-cbc
83
- idea-cfb
84
- idea-ecb
85
- idea-ofb
86
- rc2
87
- rc2-40-cbc
88
- rc2-64-cbc
89
- rc2-cbc
90
- rc2-cfb
91
- rc2-ecb
92
- rc2-ofb
93
- rc4
94
- rc4-40
95
-
96
-
97
- == Note on Patches/Pull Requests
98
-
99
- * Fork the project.
100
- * Make your feature addition or bug fix.
101
- * Add tests for it. This is important so I don't break it in a future version unintentionally.
102
- * Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
103
- * Send me a pull request. Bonus points for topic branches.