passw3rd 0.2.3 → 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -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