passw3rd 0.2.3 → 0.2.5

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.
@@ -1,10 +1,14 @@
1
+ === 0.2.5
2
+
3
+ Kill this project. It's not a good idea to use this. This is bad crypto.
4
+
1
5
  === 0.2.1 / 2011-11-8
2
6
 
3
7
  Added option to fail silently. Pretty common need in a Rails environment.
4
8
 
5
9
  === 0.2.0 / 2011-11-5
6
10
 
7
- Added acceptance tests as a contract for future features.
11
+ Added acceptance tests as a contract for future features.
8
12
  Collapsed the KeyLoader class, eliminated the KeyPair class. If for some reason you referenced those classes, things will break. But you wouldn't do that, would you?
9
13
  More testing goodness.
10
14
 
data/README.md CHANGED
@@ -1,8 +1,19 @@
1
- ![Build status](https://secure.travis-ci.org/oreoshake/passw3rd.png)
1
+ [![Build Status](https://secure.travis-ci.org/oreoshake/passw3rd.png)](http://travis-ci.org/oreoshake/passw3rd)
2
2
 
3
- It's only failing because it can't find the system ruby. If you have a solution, checkout bin/passw3rd please :)
3
+ Danger
4
+ ------------------------------------------------------------------------------
5
+ Just an FYI, this library promotes "bad crypto". I'm not a cryptographer so you'll see a lot of "maybes" and "probably"s. The
6
+ potential problem lies in the fact that the IV is reused for all values. I'm under the impression that IV
7
+ reuse can lead to the key being revealed. The possibility of this attack rises
8
+ with each encrypted value encountered. ActiveSupport's encryptor supports per-value IVs,
9
+ but that's probably still not enough as the values aren't authenticated in any way.
10
+
11
+ There is an issue open to fix this ([#32](https://github.com/oreoshake/passw3rd/issues/32)),
12
+ but I just haven't had the time. Even worse, there will need to be a migration path from the old to the new.
13
+
14
+ If you are using this to store 5-20 passwords, you're probably OK. It's better than nothing in this case.
4
15
 
5
- It will still work on your machine.
16
+ If you are using this to store a ton of records, you probably should use another encryption method.
6
17
 
7
18
  Introduction
8
19
  ------------------------------------------------------------------------------
@@ -21,7 +32,7 @@ Some advantages of keeping credentials out of source code are:
21
32
  all instances.
22
33
  6. Leaving credentials in source code leads to poor password management in
23
34
  general. If changing a credential requires you to change code, you are less
24
- likely to want to do it.
35
+ likely to want to do it.
25
36
 
26
37
 
27
38
  Status
@@ -29,6 +40,91 @@ Status
29
40
 
30
41
  This project is IN PROGRESS. File bugs and feature requests.
31
42
 
43
+ Examples
44
+ ------------------------------------------------------------------------------
45
+ Command line use
46
+ Generate key/iv in current directory by default
47
+
48
+ $ passw3rd -g
49
+ generated keys in /Users/user
50
+
51
+ $ passw3rd -g ~/Desktop/
52
+ generated keys in /Users/user/Desktop/
53
+
54
+ Create a password file
55
+
56
+ $ passw3rd -e foobar_app
57
+ Enter the password:
58
+ Wrote password to /Users/neilmatatall/foobar_app
59
+ $ passw3rd -e foobar_app -p ~/Desktop/
60
+ Enter the password:
61
+ Wrote password to /Users/neilmatatall/Desktop/foobar_app
62
+
63
+ Read a password file
64
+
65
+ $ passw3rd -d foobar_app
66
+ The password is: asdf
67
+ $ passw3rd -d foobar_app -p ~/Desktop/
68
+ The password is: asdf
69
+ ------------------------------------------------------------------------------
70
+
71
+ Options
72
+ ------------------------------------------------------------------------------
73
+ Common options per read/write operation
74
+
75
+ -d, --decrypt PATH_TO_PASSWORD Path to password file
76
+ -e, --encrypt PASSWORD_FILE Write the password to this location
77
+ -k, --key-dir KEY_PATH Use the keys specificed in this directory for encryption or decryption (default is current directory)
78
+ -p, --password-dir PATH Read and write password files to this directory (default is current directory)
79
+
80
+ Only used when generating keys
81
+
82
+ -g, --generate-key [PATH] generate key/iv and store in PATH, defaults to the current directory
83
+
84
+ Key rotation: simple
85
+ ------------------------------------------------------------------------------
86
+
87
+ $ rake rotate_keys[~/passwords,~/passwords,aes-256-cbc]
88
+
89
+ ------------------------------------------------------------------------------
90
+ Ruby on Rails config/database.yml
91
+
92
+ Example configuration in boot.rb:
93
+
94
+ ENV['passw3rd-cipher_name'] = 'aes-256-cbc'
95
+ if %w{production staging}.include? ENV['RAILS_ENV']
96
+ ENV['passw3rd-password_file_dir'] = File.expand_path('../../passwords/production', __FILE__)
97
+ ENV['passw3rd-key_file_dir'] = File.expand_path('../../passwords/production', __FILE__)
98
+ else
99
+ ENV['passw3rd-password_file_dir'] = File.expand_path('../../passwords', __FILE__)
100
+ ENV['passw3rd-key_file_dir'] = File.expand_path('../../passwords', __FILE__)
101
+ end
102
+
103
+ Then remove passwords from config files and source code
104
+
105
+ Before:
106
+
107
+ development:
108
+ adapter: mysql
109
+ database: rails_development
110
+ username: root
111
+ password: my super secret password
112
+
113
+
114
+ After:
115
+
116
+ development:
117
+ adapter: mysql
118
+ database: rails_development
119
+ username: root
120
+ password: <%= Passw3rd::PasswordService.get_password('foobar_app') %>
121
+
122
+ ------------------------------------------------------------------------------
123
+ OpenSSL command line
124
+
125
+ $ openssl enc -e -aes-256-cbc -K `cat ~/.passw3rd-encryptionKey` -iv `cat ~/.passw3rd-encryptionIV` -in README.md -out test.out
126
+ $ openssl enc -d -aes-256-cbc -K `cat ~/.passw3rd-encryptionKey` -iv `cat ~/.passw3rd-encryptionIV` -out README.md -in test.out
127
+
32
128
 
33
129
  License
34
130
  ------------------------------------------------------------------------------
@@ -56,7 +56,7 @@ module Passw3rd
56
56
 
57
57
  # decrypt password_file using the key/IV in key_path
58
58
  if mode == "decrypt"
59
- decrypted =::Passw3rd::PasswordService.get_password(password_file, :key_path => key_path)
59
+ decrypted =::Passw3rd::PasswordService.get_password(password_file, :key_path => key_path, :force => true)
60
60
  puts "The password is: #{decrypted}"
61
61
  end
62
62
 
@@ -5,7 +5,7 @@ module Passw3rd
5
5
  IV_FILE = ".passw3rd-encryptionIV"
6
6
  # more preferred ciphers first
7
7
  APPROVED_CIPHERS = %w{aes-256-cbc aes-256-cfb aes-128-cbc aes-128-cfb}
8
-
8
+
9
9
  class PasswordService
10
10
 
11
11
  class << self
@@ -38,39 +38,23 @@ module Passw3rd
38
38
  encoded_password = read_file(uri)
39
39
  decrypt(encoded_password, options[:key_path])
40
40
  rescue => e
41
- raise ArgumentError, "Could not decrypt passw3rd file #{password_file} - #{e}" if options[:force]
41
+ raise e, "Could not decrypt passw3rd file #{password_file} - #{e}" if options[:force]
42
42
  end
43
43
 
44
44
  def self.write_password_file(password, output_path, key_path = self.key_file_dir)
45
45
  enc_password = encrypt(password, key_path)
46
- base64pw = Base64.encode64(enc_password)
46
+ base64pw = Base64.encode64(enc_password)
47
47
  path = File.join(password_file_dir, output_path)
48
48
  write_file(path, base64pw)
49
49
  path
50
50
  end
51
51
 
52
52
  def self.encrypt(password, key_path = self.key_file_dir)
53
- raise ArgumentError, "password cannot be blank" if password.to_s.empty?
54
-
55
- cipher = cipher_setup(:encrypt, key_path)
56
- begin
57
- e = cipher.update(password)
58
- e << cipher.final
59
- rescue OpenSSL::Cipher::CipherError => err
60
- puts "Couldn't encrypt password."
61
- raise err
62
- end
53
+ raise "Don't use this library. It's bad crypto. Don't even listen to my recommendations."
63
54
  end
64
55
 
65
56
  def self.decrypt(cipher_text, key_path = self.key_file_dir)
66
- cipher = cipher_setup(:decrypt, key_path)
67
- begin
68
- d = cipher.update(cipher_text)
69
- d << cipher.final
70
- rescue OpenSSL::Cipher::CipherError => err
71
- puts "Couldn't decrypt password #{cipher_text}. Are you using the right keys (#{key_path})?"
72
- raise err
73
- end
57
+ raise "Don't use this library. It's bad crypto. Don't even listen to my recommendations."
74
58
  end
75
59
 
76
60
  def self.rotate_keys(args = {})
@@ -97,7 +81,7 @@ module Passw3rd
97
81
 
98
82
  passwords.each do |password|
99
83
  full_path = File.join(::Passw3rd::PasswordService.password_file_dir, password[:file])
100
- ::Passw3rd::PasswordService.write_password_file(password[:clear_password], password[:file])
84
+ ::Passw3rd::PasswordService.write_password_file(password[:clear_password], password[:file])
101
85
  puts "Wrote new password to #{full_path}"
102
86
  end
103
87
  end
@@ -105,7 +89,7 @@ module Passw3rd
105
89
  def self.create_key_iv_file(path = nil)
106
90
  unless path
107
91
  path = ::Passw3rd::PasswordService.key_file_dir
108
- end
92
+ end
109
93
 
110
94
  # d'oh!
111
95
  cipher = OpenSSL::Cipher::Cipher.new(::Passw3rd::PasswordService.cipher_name)
@@ -121,17 +105,17 @@ module Passw3rd
121
105
  end
122
106
  path
123
107
  end
124
-
108
+
125
109
  def self.key_path(path= self.key_file_dir)
126
110
  File.join(path || self.key_file_dir, KEY_FILE)
127
111
  end
128
-
112
+
129
113
  def self.iv_path(path = ::Passw3rd::PasswordService.key_file_dir)
130
114
  File.join(path || self.key_file_dir, IV_FILE)
131
- end
115
+ end
132
116
 
133
117
  protected
134
-
118
+
135
119
  def self.load_key(path = ::Passw3rd::PasswordService.key_file_dir)
136
120
  begin
137
121
  key = IO.readlines(File.expand_path(self.key_path(path)))[0]
@@ -142,11 +126,11 @@ module Passw3rd
142
126
  end
143
127
 
144
128
  {:key => [key].pack("H*"), :iv => [iv].pack("H*")}
145
- end
129
+ end
146
130
 
147
- def self.cipher_setup(method, key_path)
131
+ def self.cipher_setup(method, key_path, cipher_override = nil)
148
132
  pair = self.load_key(key_path)
149
- cipher = OpenSSL::Cipher::Cipher.new(cipher_name)
133
+ cipher = OpenSSL::Cipher::Cipher.new(cipher_override || cipher_name)
150
134
  cipher.send(method)
151
135
  cipher.key = pair[:key]
152
136
  cipher.iv = pair[:iv]
@@ -168,5 +152,11 @@ module Passw3rd
168
152
  def self.write_file path, value
169
153
  open(path, 'w') { |f| f.write value }
170
154
  end
155
+
156
+ def self.do_decrypt(cipher_text, key_path, cipher)
157
+ cipher = cipher_setup(:decrypt, key_path, cipher)
158
+ d = cipher.update(cipher_text)
159
+ d << cipher.final
160
+ end
171
161
  end
172
162
  end
@@ -1,3 +1,3 @@
1
1
  module Passw3rd
2
- Version = VERSION = '0.2.3'
2
+ Version = VERSION = '0.2.5'
3
3
  end
@@ -14,6 +14,20 @@ class PasswordServiceTest < Test::Unit::TestCase
14
14
  ::Passw3rd::PasswordService.password_file_dir = path
15
15
  ::Passw3rd::PasswordService.create_key_iv_file
16
16
  end
17
+
18
+ def test_detect_cipher
19
+ ::Passw3rd::PasswordService.cipher_name = ::Passw3rd::APPROVED_CIPHERS.last
20
+ setup_sandbox
21
+
22
+ enc = ::Passw3rd::PasswordService.encrypt(@random_string)
23
+ dec = ::Passw3rd::PasswordService.decrypt(enc)
24
+
25
+ ::Passw3rd::PasswordService.cipher_name = ::Passw3rd::APPROVED_CIPHERS.first
26
+
27
+ assert_raise(OpenSSL::Cipher::CipherError) do
28
+ ::Passw3rd::PasswordService.decrypt(enc)
29
+ end
30
+ end
17
31
 
18
32
  def test_enc_dec
19
33
  setup_sandbox
@@ -83,4 +97,6 @@ class PasswordServiceTest < Test::Unit::TestCase
83
97
 
84
98
  FileUtils.rm_rf(dir)
85
99
  end
100
+
101
+
86
102
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: passw3rd
3
3
  version: !ruby/object:Gem::Version
4
- hash: 17
4
+ hash: 29
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 2
9
- - 3
10
- version: 0.2.3
9
+ - 5
10
+ version: 0.2.5
11
11
  platform: ruby
12
12
  authors:
13
13
  - Neil Matatall
@@ -15,7 +15,8 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-11-16 00:00:00 Z
18
+ date: 2014-09-06 00:00:00 -07:00
19
+ default_executable:
19
20
  dependencies: []
20
21
 
21
22
  description: Generate a key/iv file, generate passwords, and store encrypted files in source control, keep the key/iv safe!
@@ -30,7 +31,6 @@ extra_rdoc_files: []
30
31
  files:
31
32
  - README.md
32
33
  - LICENSE
33
- - EXAMPLES.md
34
34
  - History.txt
35
35
  - lib/passw3rd/password_client.rb
36
36
  - lib/passw3rd/password_service.rb
@@ -40,6 +40,7 @@ files:
40
40
  - test/password_service_test.rb
41
41
  - spec/password_service_spec.rb
42
42
  - spec/spec_helper.rb
43
+ has_rdoc: true
43
44
  homepage: https://github.com/oreoshake/passw3rd
44
45
  licenses: []
45
46
 
@@ -69,7 +70,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
69
70
  requirements: []
70
71
 
71
72
  rubyforge_project:
72
- rubygems_version: 1.8.10
73
+ rubygems_version: 1.4.2
73
74
  signing_key:
74
75
  specification_version: 3
75
76
  summary: A simple "keep the passwords out of source code and config files".
@@ -1,85 +0,0 @@
1
- ------------------------------------------------------------------------------
2
- Command line use
3
-
4
- Generate key/iv in ~/ by default
5
-
6
- $ passw3rd -g
7
- generated keys in /Users/user
8
-
9
- $ passw3rd -g ~/Desktop/
10
- generated keys in /Users/user/Desktop/
11
-
12
- Create a password file
13
-
14
- $ passw3rd -e foobar_app
15
- Enter the password:
16
- Wrote password to /Users/neilmatatall/foobar_app
17
- $ passw3rd -e foobar_app -p ~/Desktop/
18
- Enter the password:
19
- Wrote password to /Users/neilmatatall/Desktop/foobar_app
20
-
21
- Read a password file
22
-
23
- $ passw3rd -d foobar_app
24
- The password is: asdf
25
- $ passw3rd -d foobar_app -p ~/Desktop/
26
- The password is: asdf
27
- ------------------------------------------------------------------------------
28
-
29
- Key rotation: simple
30
-
31
- [passw3rd (gh-10-key_rotation *$)]$ rake rotate_keys[~/passwords,~/passwords,aes-256-cbc]
32
-
33
-
34
- ------------------------------------------------------------------------------
35
- Manual JDBC Connection
36
-
37
- Before:
38
-
39
- Datasource ds = new Datasource();
40
- ds.setPassword("suparSekret");
41
-
42
- After:
43
-
44
- Datasource ds = new Datasource();
45
- ds.setPassword(PasswordService.getPassword(USER);
46
-
47
- ------------------------------------------------------------------------------
48
- Java properties file
49
-
50
- Before:
51
-
52
- password=suparSekret
53
-
54
- After:
55
-
56
- password=${password}
57
-
58
- ------------------------------------------------------------------------------
59
- Ruby on Rails config/database.yml
60
-
61
- initializer:
62
- ::Passw3rd::PasswordService.password_file_dir = "passwords"
63
-
64
- Before:
65
-
66
- development:
67
- adapter: mysql
68
- database: rails_development
69
- username: root
70
- password: my super secret password
71
-
72
-
73
- After:
74
-
75
- development:
76
- adapter: mysql
77
- database: rails_development
78
- username: root
79
- password: <%= PasswordService.get_password('foobar_app') -%>
80
-
81
- ------------------------------------------------------------------------------
82
- OpenSSL command line
83
-
84
- $ openssl enc -e -aes-256-cbc -K `cat ~/.passw3rd-encryptionKey` -iv `cat ~/.passw3rd-encryptionIV` -in README.md -out test.out
85
- $ openssl enc -d -aes-256-cbc -K `cat ~/.passw3rd-encryptionKey` -iv `cat ~/.passw3rd-encryptionIV` -out README.md -in test.out