phpass-ruby 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ # gem "activesupport", ">= 2.3.5"
5
+
6
+ # Add dependencies to develop your gem here.
7
+ # Include everything needed to run rake, tests, features, etc.
8
+ group :development do
9
+ gem "rspec", "~> 2.1.0"
10
+ gem "bundler", "~> 1.0.0"
11
+ gem "jeweler", "~> 1.5.1"
12
+ gem "rcov", ">= 0"
13
+ end
@@ -0,0 +1,29 @@
1
+ This is a porting of [phpass](http://www.openwall.com/phpass/)
2
+
3
+ All files within this package are in public domain.
4
+
5
+ # Install
6
+
7
+ $ gem install phpass
8
+
9
+ # Usage
10
+
11
+ require "rubygems"
12
+ require "phpass"
13
+
14
+ # 12 is password strength / calculation time. This is trade-off. Try
15
+ phpass = Phpass.new(12)
16
+
17
+ # Get hashed string. These are different result each time.
18
+ p phpass.hash('foo')
19
+ p phpass.hash('foo')
20
+ p phpass.hash('foo')
21
+
22
+ # Compare input and stored hash
23
+ known = '$P$9IQRaTwmfeRo7ud9Fh4E2PdI0S3r.L0'
24
+ p phpass.check('test12345', known) # => true
25
+ p phpass.check('test12346', known) # => false
26
+
27
+ # Caution
28
+
29
+ phpass-ruby is supporting portable(MD5) hashing only.
@@ -0,0 +1,50 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'rake'
11
+
12
+ require 'jeweler'
13
+ Jeweler::Tasks.new do |gem|
14
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
15
+ gem.name = "phpass-ruby"
16
+ gem.homepage = "http://github.com/tt25/phpass-ruby"
17
+ gem.license = "MIT"
18
+ gem.summary = %Q{TODO: one-line summary of your gem}
19
+ gem.description = %Q{TODO: longer description of your gem}
20
+ gem.email = "a@tt25.org"
21
+ gem.authors = ["uu59"]
22
+ # Include your dependencies below. Runtime dependencies are required when using your gem,
23
+ # and development dependencies are only needed for development (ie running rake tasks, tests, etc)
24
+ # gem.add_runtime_dependency 'jabber4r', '> 0.1'
25
+ # gem.add_development_dependency 'rspec', '> 1.2.3'
26
+ end
27
+ Jeweler::RubygemsDotOrgTasks.new
28
+
29
+ require 'rspec/core'
30
+ require 'rspec/core/rake_task'
31
+ RSpec::Core::RakeTask.new(:spec) do |spec|
32
+ spec.pattern = FileList['spec/**/*_spec.rb']
33
+ end
34
+
35
+ RSpec::Core::RakeTask.new(:rcov) do |spec|
36
+ spec.pattern = 'spec/**/*_spec.rb'
37
+ spec.rcov = true
38
+ end
39
+
40
+ task :default => :spec
41
+
42
+ require 'rake/rdoctask'
43
+ Rake::RDocTask.new do |rdoc|
44
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
45
+
46
+ rdoc.rdoc_dir = 'rdoc'
47
+ rdoc.title = "phpass-ruby #{version}"
48
+ rdoc.rdoc_files.include('README*')
49
+ rdoc.rdoc_files.include('lib/**/*.rb')
50
+ end
@@ -0,0 +1,40 @@
1
+ # -- coding: utf-8
2
+
3
+ require "digest/md5"
4
+ require "openssl"
5
+ require "#{File.dirname(__FILE__)}/phpass/md5.rb"
6
+
7
+ class Phpass
8
+ def initialize(iter=8)
9
+ iter = 8 unless (8..128).include?(iter)
10
+ @iter = iter
11
+ end
12
+
13
+ def hash(pw, alg=:md5)
14
+ hasher = Md5.new(@iter)
15
+ hasher.hash(pw)
16
+ end
17
+
18
+ def check(pw, hash)
19
+ hasher = Md5.new(@iter)
20
+ hasher.check(pw, hash)
21
+ end
22
+
23
+ def self.random_bytes(length)
24
+ out = ''
25
+ if File.readable?('/dev/urandom')
26
+ out = File.read('/dev/urandom', length)
27
+ end
28
+
29
+ if(out.length < length)
30
+ random_state = '%s%s' % [Time.now.to_f, $$]
31
+ out = ''
32
+ while out.length < length
33
+ rnd = Digest::MD5.hexdigest(Time.now.to_f.to_s + random_state)
34
+ out << Digest::MD5.digest(rnd)
35
+ end
36
+ out = out[0..length]
37
+ end
38
+ out
39
+ end
40
+ end
@@ -0,0 +1,74 @@
1
+ # -- coding: utf-8
2
+
3
+ require "rubygems"
4
+
5
+ class Phpass
6
+ class Md5
7
+ def initialize(stretch=8)
8
+ @itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
9
+ stretch = 8 unless (8..128).include?(stretch)
10
+ @stretch = stretch
11
+ @random_state = '%s%s' % [Time.now.to_f, $$]
12
+ end
13
+
14
+ def hash(pw)
15
+ rnd = ''
16
+ rnd = Phpass.random_bytes(6)
17
+ crypt(pw, gensalt(rnd))
18
+ end
19
+
20
+ def check(pw, hash)
21
+ crypt(pw, hash) == hash
22
+ end
23
+
24
+ private
25
+
26
+ def gensalt(input)
27
+ out = '$P$'
28
+ out << @itoa64[[@stretch + 5, 30].min]
29
+ out << encode64(input, 6)
30
+ out
31
+ end
32
+
33
+ def crypt(pw, setting)
34
+ out = '*0'
35
+ out = '*1' if setting.start_with?(out)
36
+ iter = @itoa64.index(setting[3])
37
+ return out unless (8..30).include?(iter)
38
+ count = 1 << iter
39
+ salt = setting[4...12]
40
+ return out if salt.length != 8
41
+ hash = Digest::MD5.digest(salt + pw)
42
+ while count > 0
43
+ hash = Digest::MD5.digest(hash + pw)
44
+ count -= 1
45
+ end
46
+ setting[0,12] + encode64(hash, 16)
47
+ end
48
+
49
+ def encode64(input, count)
50
+ out = ''
51
+ cur = 0
52
+ while cur < count
53
+ value = input[cur].ord
54
+ cur += 1
55
+ out << @itoa64[value & 0x3f]
56
+ if cur < count
57
+ value |= input[cur].ord << 8
58
+ end
59
+ out << @itoa64[(value >> 6) & 0x3f]
60
+ break if cur >= count
61
+ cur += 1
62
+
63
+ if cur < count
64
+ value |= input[cur].ord << 16
65
+ end
66
+ out << @itoa64[(value >> 12) & 0x3f]
67
+ break if cur >= count
68
+ cur += 1
69
+ out << @itoa64[(value >> 18) & 0x3f]
70
+ end
71
+ out
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,19 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "PhpassRuby" do
4
+ before do
5
+ @ps = Phpass.new
6
+ @correct = 'test12345'
7
+ @wrong = 'test12346'
8
+ end
9
+
10
+ it 'should correct' do
11
+ hash = @ps.hash(@correct)
12
+ @ps.check(@correct, hash).should be_true
13
+ known = '$P$9IQRaTwmfeRo7ud9Fh4E2PdI0S3r.L0'
14
+ @ps.check(@correct, known).should be_true
15
+ @ps.check(@wrong, known).should be_false
16
+ end
17
+ end
18
+
19
+
@@ -0,0 +1,12 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+ require 'rspec'
4
+ require 'phpass'
5
+
6
+ # Requires supporting files with custom matchers and macros, etc,
7
+ # in ./support/ and its subdirectories.
8
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
9
+
10
+ RSpec.configure do |config|
11
+
12
+ end
metadata ADDED
@@ -0,0 +1,130 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: phpass-ruby
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 0
9
+ version: 0.1.0
10
+ platform: ruby
11
+ authors:
12
+ - uu59
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-12-14 00:00:00 +09:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: rspec
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ~>
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 2
30
+ - 1
31
+ - 0
32
+ version: 2.1.0
33
+ type: :development
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: bundler
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ segments:
44
+ - 1
45
+ - 0
46
+ - 0
47
+ version: 1.0.0
48
+ type: :development
49
+ version_requirements: *id002
50
+ - !ruby/object:Gem::Dependency
51
+ name: jeweler
52
+ prerelease: false
53
+ requirement: &id003 !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ~>
57
+ - !ruby/object:Gem::Version
58
+ segments:
59
+ - 1
60
+ - 5
61
+ - 1
62
+ version: 1.5.1
63
+ type: :development
64
+ version_requirements: *id003
65
+ - !ruby/object:Gem::Dependency
66
+ name: rcov
67
+ prerelease: false
68
+ requirement: &id004 !ruby/object:Gem::Requirement
69
+ none: false
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ segments:
74
+ - 0
75
+ version: "0"
76
+ type: :development
77
+ version_requirements: *id004
78
+ description: phpass for ruby
79
+ email: a@tt25.org
80
+ executables: []
81
+
82
+ extensions: []
83
+
84
+ extra_rdoc_files:
85
+ - README.md
86
+ files:
87
+ - .document
88
+ - .rspec
89
+ - Gemfile
90
+ - README.md
91
+ - Rakefile
92
+ - lib/phpass.rb
93
+ - lib/phpass/md5.rb
94
+ - spec/phpass-ruby_spec.rb
95
+ - spec/spec_helper.rb
96
+ has_rdoc: true
97
+ homepage: http://github.com/tt25/phpass-ruby
98
+ licenses:
99
+ - MIT
100
+ post_install_message:
101
+ rdoc_options: []
102
+
103
+ require_paths:
104
+ - lib
105
+ required_ruby_version: !ruby/object:Gem::Requirement
106
+ none: false
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ segments:
111
+ - 0
112
+ version: "0"
113
+ required_rubygems_version: !ruby/object:Gem::Requirement
114
+ none: false
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ segments:
119
+ - 0
120
+ version: "0"
121
+ requirements: []
122
+
123
+ rubyforge_project:
124
+ rubygems_version: 1.3.7
125
+ signing_key:
126
+ specification_version: 3
127
+ summary: phpass for ruby
128
+ test_files:
129
+ - spec/phpass-ruby_spec.rb
130
+ - spec/spec_helper.rb