scl 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 043a75c0ec7aab24c5bde01c147e009b7e0bc58f
4
- data.tar.gz: 3e1bf4954baccfab324591cddcbaa1fc60f14dab
3
+ metadata.gz: dd44c29e009a373f15867aabba011afd2081eec8
4
+ data.tar.gz: fd478293a6d0cf19c22d6b13c8aac6dfbb755ecc
5
5
  SHA512:
6
- metadata.gz: eb615f84d442a67a169c804f99a2a243553c99055879a52d7479e96742f43142e69da4971657f6ead3d19bea5584f3722553e7b64193f563507e6950fe19dd2a
7
- data.tar.gz: c0f3e20309a25ff69d1e4ebb2dcfaf8e2275fee1ebd7fa48cbefeb6d379ad9a4fb1b72e0d3c2b64cceb593e26755e065be4c3bdb40095533ed71a7ab8e430c6b
6
+ metadata.gz: 40f19d23ec8425cfbe315c74b5be4329c5f494822ac54f0a3d3025bac27df4332547bb7b0e2a6546eb81ed1357dbbf9611ba36314eaeff5a3e8d0ab4ce826d75
7
+ data.tar.gz: 052ad1a09df6f1280680b433ccb9d8242abf6dfebb32ede7943ca6be47667a02dfdf2de5a2c4dfbe8e158e67067a5071e0b4639fdc754423cfbd054748600f45
data/README.md CHANGED
@@ -1,8 +1,22 @@
1
1
  # Scl (Simple Crypto Library)
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/scl`. To experiment with that code, run `bin/console` for an interactive prompt.
3
+ Scl is the Ruby *Simple Cryptography Library*. It comes with both a library for use in a Ruby codebase and a fully featured command line tool for all of your basic cryptography needs.
4
4
 
5
- TODO: Delete this and the text above, and describe your gem
5
+ As anybody in the crypto-space knows using any cryptography library that has not been extensively audited and battle-tested in a security critical system is asking for trouble, hence:<br/>
6
+ **This library is intended for use in hobbyist projects or educational purposes. Use at own risk**
7
+
8
+ For much of its functionality it is simply a fairly thin wrapper over OpenSSL functions and primitives and therefore should be quite robust and performant. It couples this with a clean and easy to use API making it a fantastic tool to learn about what cryptography has to offer.
9
+
10
+ With learning in mind it covers some of the most widely used and exciting functionality offered to us by cryptography.
11
+
12
+ * [Diffie Hellman key-exchange](#diffie-hellman-key-exchange)
13
+ * [Public-key encryption (RSA)](#rsa-encryption)
14
+ * [Public-key verification (RSA)](#rsa-verification)
15
+ * [Shamirs secret sharing](#shamirs-secret-sharing)
16
+ * [AES Block Cipher Encryption](#aes-encryption)
17
+ * [HMAC and Digests](#hmac-and-digests)
18
+
19
+ This tool provides basic insight around what each of the above has to offer us, and how you might potentially use these in unison to offer secure and/or verifiable solutions. Each of the above modules can be used from the command line interface, or imported directly into your code
6
20
 
7
21
  ## Installation
8
22
 
@@ -20,6 +34,76 @@ Or install it yourself as:
20
34
 
21
35
  $ gem install scl
22
36
 
37
+ ## Usage (per module)
38
+
39
+ ### Diffie Hellman Key Exchange
40
+ #### What is it?
41
+ Diffie–Hellman key exchange (D–H) is a method of securely exchanging cryptographic keys over a public channel and was one of the first public-key protocols as originally conceptualized by Ralph Merkle and named after Whitfield Diffie and Martin Hellman.<sup>[[1]]</sup>
42
+
43
+ #### How do I use it?
44
+ ##### CLI
45
+ ##### Library
46
+ #### Why is it great?
47
+ * You can agree on a shared secret on a public-channel without exposing anything to an eavesdropper.
48
+ * This means you do not need to trust your communication channel for it to be effective! (You could securely communicate using snail mail, smoke signals, carrier pigeons) and as long as both parties to the transmission properly secure the generated private and shared keys of the exchange you can know your communication is secure and private
49
+ * You do not need to share any secrets to complete the exchange.
50
+ * You can negotitate a new secret per transmission for perfect forward secrecy
51
+
52
+ #### How does it work?
53
+
54
+ ### RSA(Encryption)
55
+ #### What is it?
56
+ RSA can be used to encrypt and decrypt messages utilising public-key cryptography.
57
+
58
+ Public key cryptography, or asymmetrical cryptography, is any cryptographic system that uses pairs of keys: public keys which may be disseminated widely, and private keys which are known only to the owner. This accomplishes two functions: authentication, which is when the public key is used to verify that a holder of the paired private key sent the message, and encryption, whereby only the holder of the paired private key can decrypt the message encrypted with the public key.<sup>[[2]]</sup>
59
+
60
+ #### How do I use it?
61
+ ##### CLI
62
+ ##### Library
63
+ #### Why is it great?
64
+ * You can use your private key to prove a message came from you
65
+ * Anyone can use your public key to construct a message for your eyes only
66
+ * You can establish secure communications between two or more parties without the need to engage in a key-negotiation process
67
+ * See also RSA(Verification)
68
+
69
+ #### How does it work?
70
+
71
+ ### RSA(Verification)
72
+ #### What is it?
73
+ RSA can be used to generate digital signatures for a message and to compare a given signature with one generated from a digital message.
74
+
75
+ A digital signature is a mathematical scheme for demonstrating the authenticity of digital messages or documents. A valid digital signature gives a recipient reason to believe that the message was created by a known sender (authentication), that the sender cannot deny having sent the message (non-repudiation), and that the message was not altered in transit (integrity)<sup>[[3]]</sup>
76
+ #### How do I use it?
77
+ ##### CLI
78
+ ##### Library
79
+ #### Why is it great?
80
+ * See also RSA(Encryption)
81
+ #### How does it work?
82
+
83
+ ### Shamir's Secret Sharing
84
+ #### What is it?
85
+ #### How do I use it?
86
+ ##### CLI
87
+ ##### Library
88
+ #### Why is it great?
89
+ #### How does it work?
90
+
91
+ ### AES Encryption
92
+ #### What is it?
93
+ #### How do I use it?
94
+ ##### CLI
95
+ ##### Library
96
+ #### Why is it great?
97
+ #### How does it work?
98
+
99
+ ### HMAC and Digests
100
+ #### What is it?
101
+ #### How do I use it?
102
+ ##### CLI
103
+ ##### Library
104
+ #### Why is it great?
105
+ #### How does it work?
106
+
23
107
  ## CLI
24
108
 
25
109
  SCL Comes with a command line interface that allows you to perform basic encryption, decryption and key generation and key negotiation operations.
@@ -52,9 +136,6 @@ scl aes encrypt [file] # Encrypt from file
52
136
  scl aes encrypt --key="abc" [file] # Enc
53
137
  ```
54
138
 
55
- ## Usage
56
-
57
- TODO: Write usage instructions here
58
139
 
59
140
  ## Development
60
141
 
@@ -69,3 +150,7 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERN
69
150
  ## Code of Conduct
70
151
 
71
152
  Everyone interacting in the Scl project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/scl/blob/master/CODE_OF_CONDUCT.md).
153
+
154
+ [1]: https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange
155
+ [2]: https://en.wikipedia.org/wiki/Public-key_cryptography
156
+ [3]: https://en.wikipedia.org/wiki/Digital_signature
data/Rakefile CHANGED
@@ -1,2 +1,10 @@
1
1
  require "bundler/gem_tasks"
2
- task :default => :spec
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList['test/**/*_test.rb']
8
+ end
9
+
10
+ task :default => :test
data/lib/scl/aes.rb CHANGED
@@ -5,12 +5,12 @@ module Scl
5
5
  @block_size = block_size || 256
6
6
  end
7
7
 
8
- def build_cypher
8
+ def build_cipher
9
9
  OpenSSL::Cipher::AES.new(@block_size, @block_cipher)
10
10
  end
11
11
 
12
12
  def encrypt(plaintext, key=nil, iv=nil)
13
- block_cipher = build_cypher
13
+ block_cipher = build_cipher
14
14
  block_cipher.encrypt
15
15
  block_cipher.key = key ||= block_cipher.random_key
16
16
  block_cipher.iv = iv ||= block_cipher.random_iv
@@ -18,7 +18,7 @@ module Scl
18
18
  end
19
19
 
20
20
  def decrypt(ciphertext, key, iv)
21
- block_cipher = build_cypher
21
+ block_cipher = build_cipher
22
22
  block_cipher.decrypt
23
23
  block_cipher.key = key
24
24
  block_cipher.iv = iv
@@ -42,6 +42,16 @@ module Scl
42
42
  )
43
43
  end
44
44
 
45
+ help <<-HELP,
46
+ ciphers. Prints a list of supported ciphers
47
+
48
+ e.g
49
+ scl aes ciphers
50
+ HELP
51
+ def ciphers
52
+ puts OpenSSL::Cipher.ciphers.select{|x| x[/^aes/]}
53
+ end
54
+
45
55
  private
46
56
  def aes
47
57
  Scl::AES.new(args.block_size, args.block_cipher)
@@ -46,7 +46,6 @@ module Scl
46
46
  case "#{format}".strip
47
47
  when "base64" then Format::BASE64
48
48
  when "qrcode" then Format::QRCODE
49
- when "base64" then Format::BASE64
50
49
  when "words" then Format::WORDS
51
50
  when "hex" then Format::HEX
52
51
  when "binary","text","none" then Format::BINARY
@@ -18,7 +18,7 @@ module Scl
18
18
  Output.new(result.public.export, '.pub'),
19
19
  Output.new(result.private.export, '.priv')
20
20
  )
21
- rescue StandardError => e
21
+ rescue StandardError
22
22
  raise ControlError.new("Couldn't generate key of size #{args.key_size}")
23
23
  end
24
24
  end
data/lib/scl/digest.rb CHANGED
@@ -18,7 +18,7 @@ module Scl
18
18
  def self.digest_exists?(digest)
19
19
  begin
20
20
  OpenSSL::Digest.const_get(digest.upcase)
21
- rescue NameError => e
21
+ rescue NameError
22
22
  puts "Couldn't get digest type. #{digest}"
23
23
  puts "Try $ scl digest list – for a list of supported digests"
24
24
  return false
@@ -1,7 +1,7 @@
1
1
  module Scl
2
2
  class Scl::Auto < Scl::Format
3
3
  def encode(data)
4
- sorted = (data.chars.map(&:ord).uniq.sort) - [10]
4
+ sorted = (data.force_encoding("binary").chars.map(&:ord).uniq.sort) - [10]
5
5
  if sorted.first < 32 || sorted.max > 126
6
6
  Scl::Format::BASE64.encode(data)
7
7
  else
@@ -11,7 +11,7 @@ module Scl
11
11
 
12
12
  def decode(data)
13
13
  png = Regexp.new("\x89PNG".force_encoding("binary"))
14
- if /^#{png}/ === data
14
+ if /^#{png}/ === data.force_encoding("binary")
15
15
  Scl::Format::QRCODE.decode(data)
16
16
  elsif data[/[^A-Za-z0-9\+\/\n=]/]
17
17
  Scl::Format::BINARY.decode(data)
@@ -17,7 +17,7 @@ module Scl
17
17
  b1 = (bytes >> 8) & 255
18
18
  [b1, b2]
19
19
  end.flatten
20
- bytes.map(&:chr).join
20
+ bytes.map(&:chr).join.gsub(/\x00$/,'')
21
21
  end
22
22
  end
23
23
  end
data/lib/scl/rsa.rb CHANGED
@@ -9,13 +9,14 @@ module Scl
9
9
  @public = public
10
10
  @private = private
11
11
  end
12
+ @output_encoder = output_encoder
12
13
  @public = Key.new(@public)
13
14
  @private = Key.new(@private)
14
15
  end
15
16
 
16
17
  def save(dir, name='rsa-keypair')
17
- IO.write(File.join(dir, "#{name}.pub"), output_encoder.encode(@public.export))
18
- IO.write(File.join(dir, "#{name}.priv"), output_encoder.encode(@private.export))
18
+ IO.write(File.join(dir, "#{name}.pub"), @output_encoder.encode(@public.export))
19
+ IO.write(File.join(dir, "#{name}.priv"), @output_encoder.encode(@private.export))
19
20
  dir
20
21
  end
21
22
 
@@ -24,8 +25,8 @@ module Scl
24
25
  RSA.new(public: rsa_pair.public_key, private: rsa_pair)
25
26
  end
26
27
 
27
- def self.encrypt(msg)
28
- pair = self.generate
28
+ def self.encrypt(msg, key_size=1024)
29
+ pair = self.generate(key_size)
29
30
  [pair.private.export, pair.public.export, pair.private.encrypt(msg)]
30
31
  end
31
32
 
@@ -13,39 +13,16 @@ module Scl
13
13
  @shares = shares
14
14
  end
15
15
 
16
- def random()
17
- @seen ||= { nil => true}
18
- number = Random.rand(1...PRIME) while @seen[number]
19
- @seen[number] = true
20
- OpenSSL::BN.new(number)
21
- end
22
-
23
- def chunks(secret)
24
- Enumerator.new do |enum|
25
- as_hex = secret.each_byte.map{|b| b.to_s(16).rjust(2, '0') }.join
26
- as_hex.chars.each_slice(64) do |slice|
27
- chunk = OpenSSL::BN.new(slice.join.ljust(64, ?0), 16)
28
- enum << chunk
29
- end
30
- end
31
- end
32
-
33
- def evaluate_polynomial(polynomial, x)
34
- polynomial.reverse.reduce(OpenSSL::BN.new(0)) do |mem, value|
35
- ((mem * x) % PRIME + value) % PRIME
36
- end
37
- end
38
-
39
16
  def generate(secret)
40
17
  polynomials = chunks(secret).map do |chunk|
41
- polynomial = [chunk] + (@minimum - 1).times.map do |i|
18
+ [chunk] + (@minimum - 1).times.map do |i|
42
19
  random
43
20
  end
44
21
  end
45
22
 
46
23
  @shares.times.map do |i|
47
24
  result = ''
48
- poly_result = polynomials.map do |polynomial|
25
+ polynomials.map do |polynomial|
49
26
  x = random
50
27
  y = evaluate_polynomial(polynomial, x)
51
28
  result << base64_encode(x)
@@ -55,34 +32,7 @@ module Scl
55
32
  end
56
33
  end
57
34
 
58
- def base64_encode(number)
59
- return ::Base64.urlsafe_encode64(number.to_s(16).rjust(64, ?0).scan(/../).map{|x| x.hex.chr}.join)
60
- end
61
-
62
- def self.base64_decode(number)
63
- ::Base64.urlsafe_decode64(number).chars.map{|x| "0#{x.ord.to_s(16)}"[-2..-1] }.join.rjust(64, ?0).hex
64
- end
65
-
66
- def self.extended_gcd(a, b)
67
- abs = ->(v){ v < 0 ? v * -1 : v}
68
- last_remainder, remainder = abs[a], abs[b]
69
- x, last_x, y, last_y = 0, 1, 1, 0
70
- while remainder != 0
71
- last_remainder, (quotient, remainder) = remainder, last_remainder./(remainder)
72
- x, last_x = last_x - quotient*x, x
73
- y, last_y = last_y - quotient*y, y
74
- end
75
-
76
- return last_remainder, last_x * (a < 0 ? -1 : 1)
77
- end
78
-
79
- def self.mod_inverse(e, p=PRIME)
80
- g, x = extended_gcd(e, p)
81
- x % p
82
- end
83
-
84
35
  def self.combine(shares, encoder: nil)
85
- abs = ->(v){ v < 0 ? v * -1 : v}
86
36
  decoded = shares.map do |share|
87
37
  share = encoder && encoder != Format::BASE64 ? encoder.decode(share) : share
88
38
  share.chars.each_slice(ENCODED_CHUNK_SIZE).map(&:join).each_slice(2).map do |random, polynomial|
@@ -118,5 +68,56 @@ module Scl
118
68
  }
119
69
  end.join
120
70
  end
71
+
72
+ private
73
+ def random()
74
+ @seen ||= { nil => true}
75
+ number = Random.rand(1...PRIME) while @seen[number]
76
+ @seen[number] = true
77
+ OpenSSL::BN.new(number)
78
+ end
79
+
80
+ def chunks(secret)
81
+ Enumerator.new do |enum|
82
+ as_hex = secret.each_byte.map{|b| b.to_s(16).rjust(2, '0') }.join
83
+ as_hex.chars.each_slice(64) do |slice|
84
+ chunk = OpenSSL::BN.new(slice.join.ljust(64, ?0), 16)
85
+ enum << chunk
86
+ end
87
+ end
88
+ end
89
+
90
+ def evaluate_polynomial(polynomial, x)
91
+ polynomial.reverse.reduce(OpenSSL::BN.new(0)) do |mem, value|
92
+ ((mem * x) % PRIME + value) % PRIME
93
+ end
94
+ end
95
+
96
+
97
+ def base64_encode(number)
98
+ return ::Base64.urlsafe_encode64(number.to_s(16).rjust(64, ?0).scan(/../).map{|x| x.hex.chr}.join)
99
+ end
100
+
101
+ def self.base64_decode(number)
102
+ ::Base64.urlsafe_decode64(number).chars.map{|x| "0#{x.ord.to_s(16)}"[-2..-1] }.join.rjust(64, ?0).hex
103
+ end
104
+
105
+ def self.extended_gcd(a, b)
106
+ abs = ->(v){ v < 0 ? v * -1 : v}
107
+ last_remainder, remainder = abs[a], abs[b]
108
+ x, last_x, y, last_y = 0, 1, 1, 0
109
+ while remainder != 0
110
+ last_remainder, (quotient, remainder) = remainder, last_remainder./(remainder)
111
+ x, last_x = last_x - quotient*x, x
112
+ y, last_y = last_y - quotient*y, y
113
+ end
114
+
115
+ return last_remainder, last_x * (a < 0 ? -1 : 1)
116
+ end
117
+
118
+ def self.mod_inverse(e, p=PRIME)
119
+ _, x = extended_gcd(e, p)
120
+ x % p
121
+ end
121
122
  end
122
123
  end
data/lib/scl/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Scl
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
data/scl.gemspec CHANGED
@@ -8,7 +8,7 @@ Gem::Specification.new do |spec|
8
8
  spec.version = Scl::VERSION
9
9
  spec.authors = ["Wouter Coppieters"]
10
10
  spec.email = ["wouter@youdo.co.nz"]
11
-
11
+ spec.homepage = "https://github.com/wouterken/scl"
12
12
  spec.summary = "Simple crypto library"
13
13
  spec.description = "Simple crypto library"
14
14
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: scl
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Wouter Coppieters
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-11-12 00:00:00.000000000 Z
11
+ date: 2017-11-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -94,7 +94,7 @@ files:
94
94
  - lib/scl/secret_share.rb
95
95
  - lib/scl/version.rb
96
96
  - scl.gemspec
97
- homepage:
97
+ homepage: https://github.com/wouterken/scl
98
98
  licenses: []
99
99
  metadata: {}
100
100
  post_install_message: