binary42-shared-secret 1.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.
- data/README +1 -0
- data/bin/secrets +17 -0
- data/lib/shared_secret.rb +114 -0
- metadata +63 -0
data/README
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Shared secrets are annoyingly hard to control. This tool helps create some simple ways to communicate information in very few steps.
|
data/bin/secrets
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Support running this as a gem or for development
|
4
|
+
if $0 =~ /-dev$/
|
5
|
+
require 'rubygems'
|
6
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__) + '/../lib')
|
7
|
+
require 'shared_secret'
|
8
|
+
else
|
9
|
+
require 'rubygems'
|
10
|
+
gem 'shared-secret'
|
11
|
+
require 'shared_secret'
|
12
|
+
end
|
13
|
+
|
14
|
+
require 'json'
|
15
|
+
require 'openssl'
|
16
|
+
|
17
|
+
SharedSecret.run
|
@@ -0,0 +1,114 @@
|
|
1
|
+
class SharedSecret
|
2
|
+
|
3
|
+
attr_reader :mode
|
4
|
+
|
5
|
+
def self.run
|
6
|
+
app = SharedSecret.new(ARGF)
|
7
|
+
output = app.process
|
8
|
+
label = "--- OUTPUT (#{app.mode}) ---"
|
9
|
+
STDERR.puts label
|
10
|
+
puts output
|
11
|
+
STDERR.puts "-" * label.size
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize(io)
|
15
|
+
if ARGV.size == 0
|
16
|
+
STDERR.puts "Please enter the message to be processed followd by ^D:"
|
17
|
+
end
|
18
|
+
@input = io.read
|
19
|
+
@mode = encrypted_input? ? :decrypt : :encrypt
|
20
|
+
end
|
21
|
+
|
22
|
+
def process
|
23
|
+
case @mode
|
24
|
+
when :decrypt
|
25
|
+
decrypt(@input)
|
26
|
+
when :encrypt
|
27
|
+
encrypt(@input)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def decrypt(cypher)
|
32
|
+
message = JSON.parse(@input.unpack('m')[0])['shared-secret']
|
33
|
+
cipher = OpenSSL::Cipher::Cipher.new(message['cipher'])
|
34
|
+
digest = OpenSSL::Digest::Digest.new(message['digest'])
|
35
|
+
digest << prompt('secret key?')
|
36
|
+
cipher.key = expand_key(digest.digest)
|
37
|
+
if message['iv']
|
38
|
+
cipher.iv = message['iv'].unpack('m')[0]
|
39
|
+
else
|
40
|
+
cipher.iv = expand_key(digest.digest)
|
41
|
+
end
|
42
|
+
cipher.decrypt
|
43
|
+
cipher.update(message['message'].unpack('m')[0]) + cipher.final
|
44
|
+
end
|
45
|
+
|
46
|
+
def encrypt(text)
|
47
|
+
cipher_algorithm = select_cipher
|
48
|
+
cipher = OpenSSL::Cipher::Cipher.new(cipher_algorithm)
|
49
|
+
# TODO: support more digest types including SHA256 and
|
50
|
+
# cipher texts.
|
51
|
+
digest = OpenSSL::Digest::Digest.new('sha1')
|
52
|
+
digest << prompt('secret key?')
|
53
|
+
cipher.key = expand_key(digest.digest)
|
54
|
+
cipher.iv = expand_key(digest.digest)
|
55
|
+
cipher.encrypt
|
56
|
+
message = cipher.update(text) + cipher.final
|
57
|
+
[{'shared-secret' => {
|
58
|
+
'cipher' => cipher_algorithm,
|
59
|
+
'digest' => 'sha1',
|
60
|
+
'message' => [message].pack('m')
|
61
|
+
}}.to_json].pack('m')
|
62
|
+
end
|
63
|
+
|
64
|
+
def select_cipher
|
65
|
+
loop do
|
66
|
+
algo = prompt('cipher algorithm (l to list)?', :string, 'bf')
|
67
|
+
if algo == 'l'
|
68
|
+
puts OpenSSL::Cipher.ciphers
|
69
|
+
next
|
70
|
+
end
|
71
|
+
break algo
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
def encrypted_input?
|
78
|
+
message = @input.unpack('m')[0]
|
79
|
+
JSON.parse(message).has_key? 'shared-secret'
|
80
|
+
rescue
|
81
|
+
false
|
82
|
+
end
|
83
|
+
|
84
|
+
def expand_key(key)
|
85
|
+
key * 4
|
86
|
+
end
|
87
|
+
|
88
|
+
def prompt(msg, type = :string, default = nil)
|
89
|
+
STDERR.print "#{msg} "
|
90
|
+
STDERR.print "(#{default}) " if default != nil
|
91
|
+
string = gets.chomp
|
92
|
+
return default if string == ''
|
93
|
+
case type
|
94
|
+
when :string
|
95
|
+
string
|
96
|
+
when :integer
|
97
|
+
string.to_i
|
98
|
+
when :float
|
99
|
+
string.to_f
|
100
|
+
when :boolean
|
101
|
+
case string
|
102
|
+
when /^(yes|y|t|true)$/i
|
103
|
+
true
|
104
|
+
when /^(no|n|f|false)$/i
|
105
|
+
false
|
106
|
+
else
|
107
|
+
default
|
108
|
+
end
|
109
|
+
else
|
110
|
+
default
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
metadata
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: binary42-shared-secret
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: "1.0"
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Brian Mitchell
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-01-11 00:00:00 -08:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: json
|
17
|
+
version_requirement:
|
18
|
+
version_requirements: !ruby/object:Gem::Requirement
|
19
|
+
requirements:
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: "0"
|
23
|
+
version:
|
24
|
+
description:
|
25
|
+
email: brian.mitchell@excoventures.com
|
26
|
+
executables:
|
27
|
+
- secrets
|
28
|
+
extensions: []
|
29
|
+
|
30
|
+
extra_rdoc_files: []
|
31
|
+
|
32
|
+
files:
|
33
|
+
- README
|
34
|
+
- lib/shared_secret.rb
|
35
|
+
- bin/secrets
|
36
|
+
has_rdoc: false
|
37
|
+
homepage: http://shared-secret.tarball.me/
|
38
|
+
post_install_message:
|
39
|
+
rdoc_options: []
|
40
|
+
|
41
|
+
require_paths:
|
42
|
+
- lib
|
43
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: "0"
|
48
|
+
version:
|
49
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: "0"
|
54
|
+
version:
|
55
|
+
requirements: []
|
56
|
+
|
57
|
+
rubyforge_project:
|
58
|
+
rubygems_version: 1.2.0
|
59
|
+
signing_key:
|
60
|
+
specification_version: 2
|
61
|
+
summary: A simple way to share secrets
|
62
|
+
test_files: []
|
63
|
+
|