dgen 0.2.0 → 0.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.
- checksums.yaml +4 -4
- data/lib/dgen/base.rb +58 -33
- data/lib/dgen/outputfile.rb +76 -0
- data/lib/dgen/passgen.rb +66 -17
- metadata +24 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4cfb3588e2b4bcadcad552501b70b42ea1d31ec2
|
4
|
+
data.tar.gz: 016f9d876d44657a84c05e5c51a136cdd8eb9e3e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e382e30496b8935d16c985fda4906a5191831d6d2c4add1227e162cc0efb4ca143f6aee849c6058ad5a37b86aee1109903658655aee7e0e5ce19501349db10bf
|
7
|
+
data.tar.gz: b0755d41f68d3a493dbacbfbd510979807b4677f4315a0d9a74f06b613ab56de66086b2b5125039f9a7f784817561b69d0284fec87947713370f2fe0651ba85d
|
data/lib/dgen/base.rb
CHANGED
@@ -1,36 +1,17 @@
|
|
1
|
-
|
1
|
+
##
|
2
|
+
# Base Script
|
2
3
|
#
|
3
|
-
#
|
4
|
-
#
|
5
|
-
#
|
6
|
-
# == Usage
|
7
|
-
#
|
8
|
-
# dgen [OPTIONS]
|
9
|
-
#
|
10
|
-
# -h, --help:
|
11
|
-
# show help
|
12
|
-
#
|
13
|
-
# -i, --interactive:
|
14
|
-
# use the interactive menu to generate passphrases
|
4
|
+
# This script handles the behavior of the program based on the options
|
5
|
+
# provided by the user.
|
15
6
|
#
|
16
7
|
# Copyright 2015 Richard Davis GPL v3
|
17
8
|
require 'optparse'
|
18
|
-
require 'dgen/passgen'
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
p_length = gets.chomp.to_i
|
25
|
-
path = File.expand_path(File.join(File.dirname(__FILE__),
|
26
|
-
'..',
|
27
|
-
'assets',
|
28
|
-
'word-list.txt'))
|
29
|
-
f = File.new(path, 'r')
|
30
|
-
phrase = PassGen.new.generate_phrase(n_words, p_length, f)
|
31
|
-
puts "Passphrase with spaces: '#{phrase}'"
|
32
|
-
puts "Passphrase without spaces: '#{phrase.delete(' ')}'"
|
33
|
-
f.close
|
9
|
+
require 'dgen/passgen.rb'
|
10
|
+
require 'dgen/outputfile.rb'
|
11
|
+
|
12
|
+
trap('INT') do
|
13
|
+
puts 'Terminating...'
|
14
|
+
exit
|
34
15
|
end
|
35
16
|
|
36
17
|
options = {}
|
@@ -38,8 +19,17 @@ options = {}
|
|
38
19
|
optparse = OptionParser.new do |opts|
|
39
20
|
opts.banner = 'Usage: dgen [options]'
|
40
21
|
|
41
|
-
opts.on('-
|
42
|
-
options[:
|
22
|
+
opts.on('-s', '--single', 'Generate a single passphrase') do
|
23
|
+
options[:single] = true
|
24
|
+
end
|
25
|
+
|
26
|
+
opts.on('-b', '--batch', 'Generate multiple passphrases') do
|
27
|
+
options[:batch] = true
|
28
|
+
end
|
29
|
+
|
30
|
+
opts.on('-o', '--open file', 'Opens encrypted output file') do |file|
|
31
|
+
options[:open] = true
|
32
|
+
options[:file] = file
|
43
33
|
end
|
44
34
|
|
45
35
|
opts.on('-h', '--help', 'Display this screen') do
|
@@ -50,8 +40,43 @@ end
|
|
50
40
|
|
51
41
|
optparse.parse!
|
52
42
|
|
53
|
-
if options[:
|
54
|
-
|
43
|
+
if options[:open]
|
44
|
+
begin
|
45
|
+
OutputFile.open_ofile(options[:file])
|
46
|
+
exit
|
47
|
+
rescue
|
48
|
+
puts 'An error occurred while trying to open the file.'
|
49
|
+
exit
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
print 'Number of words for phrase (recommended minimum is 6 words) => '
|
54
|
+
n_words = gets.chomp.to_i
|
55
|
+
print 'Length of passphrase (recommended minimum is 17 characters) => '
|
56
|
+
p_length = gets.chomp.to_i
|
57
|
+
|
58
|
+
if options[:single]
|
59
|
+
single_pass = PassGen.single(n_words, p_length)
|
60
|
+
puts 'Save this passphrase in an encrypted file? (Y/N) => '
|
61
|
+
save = gets.chomp
|
62
|
+
exit unless save.upcase == 'Y'
|
63
|
+
begin
|
64
|
+
OutputFile.save_pass(single_pass)
|
65
|
+
rescue
|
66
|
+
puts 'Unable to save passphrase to output file.'
|
67
|
+
exit
|
68
|
+
end
|
69
|
+
elsif options[:batch]
|
70
|
+
batch_pass = PassGen.batch(n_words, p_length)
|
71
|
+
puts 'Save the passphrases in an encrypted file? (Y/N) => '
|
72
|
+
save = gets.chomp
|
73
|
+
exit unless save.upcase == 'Y'
|
74
|
+
begin
|
75
|
+
OutputFile.save_batch(batch_pass)
|
76
|
+
rescue
|
77
|
+
puts 'Unable to save passphrases to output file.'
|
78
|
+
exit
|
79
|
+
end
|
55
80
|
else
|
56
81
|
puts 'You did not enter a valid option. Try --help.'
|
57
82
|
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
##
|
2
|
+
# OutputFile Module
|
3
|
+
#
|
4
|
+
# This module provides the methods that enable saving generated passwords
|
5
|
+
# securely to a file.
|
6
|
+
#
|
7
|
+
# The encryption algorithm used is Blowfish, developed by Bruce Schneier.
|
8
|
+
#
|
9
|
+
# Copyright 2015 Richard Davis GPL v3
|
10
|
+
require 'crypt/blowfish'
|
11
|
+
|
12
|
+
##
|
13
|
+
# Provides the output file module for use as a mixin.
|
14
|
+
#
|
15
|
+
module OutputFile
|
16
|
+
##
|
17
|
+
# Encrypts a given passphrase.
|
18
|
+
#
|
19
|
+
def self.encrypt(phrase, key)
|
20
|
+
blowfish = Crypt::Blowfish.new(key)
|
21
|
+
e_phrase = blowfish.encrypt_string(phrase)
|
22
|
+
e_phrase
|
23
|
+
end
|
24
|
+
|
25
|
+
##
|
26
|
+
# Decrypts a given passphrase.
|
27
|
+
#
|
28
|
+
def self.decrypt(e_phrase, key)
|
29
|
+
blowfish = Crypt::Blowfish.new(key)
|
30
|
+
phrase = blowfish.decrypt_string(e_phrase)
|
31
|
+
phrase
|
32
|
+
end
|
33
|
+
|
34
|
+
##
|
35
|
+
# Saves passphrase to a file.
|
36
|
+
#
|
37
|
+
def self.save_pass(phrase)
|
38
|
+
print 'Enter name for output file => '
|
39
|
+
o_file = gets.chomp
|
40
|
+
f = File.open("#{o_file}", 'w+')
|
41
|
+
print 'Enter a key for encryption => '
|
42
|
+
key = gets.chomp
|
43
|
+
e_phrase = encrypt(phrase, key)
|
44
|
+
f.puts e_phrase
|
45
|
+
f.close
|
46
|
+
end
|
47
|
+
|
48
|
+
##
|
49
|
+
# Saves passphrases to a file.
|
50
|
+
#
|
51
|
+
def self.save_batch(phrase)
|
52
|
+
print 'Enter name for output file => '
|
53
|
+
o_file = gets.chomp
|
54
|
+
f = File.open("#{o_file}", 'w+')
|
55
|
+
print 'Enter a key for encryption => '
|
56
|
+
key = gets.chomp
|
57
|
+
phrase.each do |p|
|
58
|
+
e_phrase = encrypt(p, key)
|
59
|
+
f.puts e_phrase
|
60
|
+
end
|
61
|
+
f.close
|
62
|
+
end
|
63
|
+
|
64
|
+
##
|
65
|
+
# Opens a previously saved output file for reading.
|
66
|
+
#
|
67
|
+
def self.open_ofile(file)
|
68
|
+
print 'Enter a key for decryption => '
|
69
|
+
key = gets.chomp
|
70
|
+
File.foreach(file) do |l|
|
71
|
+
e_phrase = l.chomp
|
72
|
+
phrase = decrypt(e_phrase, key)
|
73
|
+
puts "Decrypted passphrase: '#{phrase}'"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
data/lib/dgen/passgen.rb
CHANGED
@@ -1,11 +1,22 @@
|
|
1
|
-
|
1
|
+
##
|
2
|
+
# PassGen Module
|
3
|
+
#
|
4
|
+
# This module provides the methods that compose the password generator.
|
5
|
+
#
|
6
|
+
# The algorithm used to generate passwords is the Diceware method, developed
|
7
|
+
# by Arnold Reinhold.
|
8
|
+
#
|
2
9
|
# Copyright 2015 Richard Davis GPL v3
|
3
10
|
require 'securerandom'
|
4
11
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
12
|
+
##
|
13
|
+
# Provides the password generation module for use as a mixin.
|
14
|
+
#
|
15
|
+
module PassGen
|
16
|
+
##
|
17
|
+
# Creates an array of random numbers generated securely.
|
18
|
+
#
|
19
|
+
def self.roll_nums
|
9
20
|
numbers = []
|
10
21
|
5.times do
|
11
22
|
numbers.push(SecureRandom.random_number(6) + 1)
|
@@ -14,9 +25,22 @@ class PassGen
|
|
14
25
|
num
|
15
26
|
end
|
16
27
|
|
17
|
-
|
18
|
-
|
19
|
-
|
28
|
+
##
|
29
|
+
# Opens and returns the file containing the diceware word list.
|
30
|
+
#
|
31
|
+
def self.open_wordlist
|
32
|
+
path = File.expand_path(File.join(File.dirname(__FILE__),
|
33
|
+
'..',
|
34
|
+
'assets',
|
35
|
+
'word-list.txt'))
|
36
|
+
wordlist = File.new(path, 'r')
|
37
|
+
wordlist
|
38
|
+
end
|
39
|
+
|
40
|
+
##
|
41
|
+
# Chooses words from the diceware word list for the passphrase.
|
42
|
+
#
|
43
|
+
def self.find_word(file, number)
|
20
44
|
File.foreach(file) do |line|
|
21
45
|
num = line.slice(0, 5)
|
22
46
|
@word = line.slice(6..-2)
|
@@ -25,22 +49,47 @@ class PassGen
|
|
25
49
|
@word
|
26
50
|
end
|
27
51
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
end
|
33
|
-
|
34
|
-
# generates and returns the pass phrase
|
35
|
-
def generate_phrase(n_words, p_length, file)
|
52
|
+
##
|
53
|
+
# Generates and returns the passphrase.
|
54
|
+
#
|
55
|
+
def self.make_phrase(n_words, p_length, file)
|
36
56
|
loop do
|
37
57
|
words = []
|
38
58
|
n_words.times do
|
39
59
|
words.push(find_word(file, roll_nums))
|
40
60
|
end
|
41
|
-
@pass_phrase =
|
61
|
+
@pass_phrase = words.join(' ')
|
42
62
|
break unless @pass_phrase.length < p_length
|
43
63
|
end
|
44
64
|
@pass_phrase
|
45
65
|
end
|
66
|
+
|
67
|
+
##
|
68
|
+
# Produces and displays a single passphrase.
|
69
|
+
#
|
70
|
+
def self.single(n_words, p_length)
|
71
|
+
f = open_wordlist
|
72
|
+
phrase = make_phrase(n_words, p_length, f)
|
73
|
+
puts "Passphrase with spaces: '#{phrase}'"
|
74
|
+
puts "Passphrase without spaces: '#{phrase.delete(' ')}'"
|
75
|
+
f.close
|
76
|
+
phrase
|
77
|
+
end
|
78
|
+
|
79
|
+
##
|
80
|
+
# Produces and displays multiple passphrases.
|
81
|
+
#
|
82
|
+
def self.batch(n_words, p_length)
|
83
|
+
f = open_wordlist
|
84
|
+
phrase = []
|
85
|
+
print 'How many passphrases to generate? => '
|
86
|
+
num_pass = gets.chomp.to_i
|
87
|
+
num_pass.times do |i|
|
88
|
+
phrase.push(make_phrase(n_words, p_length, f))
|
89
|
+
puts "Passphrase with spaces: '#{phrase[i]}'"
|
90
|
+
puts "Passphrase without spaces: '#{phrase[i].delete(' ')}'"
|
91
|
+
end
|
92
|
+
f.close
|
93
|
+
phrase
|
94
|
+
end
|
46
95
|
end
|
metadata
CHANGED
@@ -1,15 +1,35 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dgen
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Richard Davis
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-11-
|
12
|
-
dependencies:
|
11
|
+
date: 2015-11-25 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: crypt
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.2'
|
20
|
+
- - '>='
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 2.2.1
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '2.2'
|
30
|
+
- - '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 2.2.1
|
13
33
|
description: |2
|
14
34
|
Using the diceware method to generate passwords results in stronger passwords
|
15
35
|
that are more resistant to cracking. This project implements the diceware
|
@@ -24,6 +44,7 @@ files:
|
|
24
44
|
- lib/assets/word-list.txt
|
25
45
|
- lib/dgen.rb
|
26
46
|
- lib/dgen/base.rb
|
47
|
+
- lib/dgen/outputfile.rb
|
27
48
|
- lib/dgen/passgen.rb
|
28
49
|
- test/test_dgen.rb
|
29
50
|
homepage: https://github.com/d3d1rty/dgen
|