crypto_laser 0.0.2 → 0.0.3

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/.gitignore ADDED
@@ -0,0 +1,7 @@
1
+ .DS_Store
2
+ *~
3
+ /.rake_test_cache
4
+ /.idea/workspace.xml
5
+ /tmp
6
+ /log/*.log
7
+ /.scratch_dir
data/.idea/.name ADDED
@@ -0,0 +1 @@
1
+ crypto_laser
data/.idea/.rakeTasks ADDED
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <Settings><!--This file was automatically generated by Ruby plugin.
3
+ You are allowed to:
4
+ 1. Remove rake task
5
+ 2. Add existing rake tasks
6
+ To add existing rake tasks automatically delete this file and reload the project.
7
+ --><RakeGroup description="" fullCmd="" taksId="rake"><RakeTask description="Run specs and features (default)" fullCmd="default" taksId="default" /><RakeTask description="Run specs" fullCmd="spec" taksId="spec" /></RakeGroup></Settings>
@@ -0,0 +1,20 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <module type="RUBY_MODULE" version="4">
3
+ <component name="NewModuleRootManager">
4
+ <content url="file://$MODULE_DIR$" />
5
+ <orderEntry type="inheritedJdk" />
6
+ <orderEntry type="sourceFolder" forTests="false" />
7
+ <orderEntry type="library" scope="PROVIDED" name="aead (v1.6.1, RVM: ruby-1.9.3-p194 [crypto_laser]) [gem]" level="application" />
8
+ <orderEntry type="library" scope="PROVIDED" name="bundler (v1.2.1, RVM: ruby-1.9.3-p194 [crypto_laser]) [gem]" level="application" />
9
+ <orderEntry type="library" scope="PROVIDED" name="diff-lcs (v1.1.3, RVM: ruby-1.9.3-p194 [crypto_laser]) [gem]" level="application" />
10
+ <orderEntry type="library" scope="PROVIDED" name="macaddr (v1.6.1, RVM: ruby-1.9.3-p194 [crypto_laser]) [gem]" level="application" />
11
+ <orderEntry type="library" scope="PROVIDED" name="pivotal_git_scripts (v1.1.4, RVM: ruby-1.9.3-p194 [crypto_laser]) [gem]" level="application" />
12
+ <orderEntry type="library" scope="PROVIDED" name="rake (v10.0.3, RVM: ruby-1.9.3-p194 [crypto_laser]) [gem]" level="application" />
13
+ <orderEntry type="library" scope="PROVIDED" name="rspec (v2.12.0, RVM: ruby-1.9.3-p194 [crypto_laser]) [gem]" level="application" />
14
+ <orderEntry type="library" scope="PROVIDED" name="rspec-core (v2.12.1, RVM: ruby-1.9.3-p194 [crypto_laser]) [gem]" level="application" />
15
+ <orderEntry type="library" scope="PROVIDED" name="rspec-expectations (v2.12.0, RVM: ruby-1.9.3-p194 [crypto_laser]) [gem]" level="application" />
16
+ <orderEntry type="library" scope="PROVIDED" name="rspec-mocks (v2.12.0, RVM: ruby-1.9.3-p194 [crypto_laser]) [gem]" level="application" />
17
+ <orderEntry type="library" scope="PROVIDED" name="systemu (v2.5.2, RVM: ruby-1.9.3-p194 [crypto_laser]) [gem]" level="application" />
18
+ </component>
19
+ </module>
20
+
@@ -0,0 +1,5 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
4
+ </project>
5
+
data/.idea/misc.xml ADDED
@@ -0,0 +1,5 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="ProjectRootManager" version="2" project-jdk-name="RVM: ruby-1.9.3-p194 [crypto_laser]" project-jdk-type="RUBY_SDK" />
4
+ </project>
5
+
data/.idea/modules.xml ADDED
@@ -0,0 +1,9 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="ProjectModuleManager">
4
+ <modules>
5
+ <module fileurl="file://$PROJECT_DIR$/.idea/crypto_laser.iml" filepath="$PROJECT_DIR$/.idea/crypto_laser.iml" />
6
+ </modules>
7
+ </component>
8
+ </project>
9
+
@@ -0,0 +1,5 @@
1
+ <component name="DependencyValidationManager">
2
+ <state>
3
+ <option name="SKIP_IMPORT_STATEMENTS" value="false" />
4
+ </state>
5
+ </component>
data/.idea/vcs.xml ADDED
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="VcsDirectoryMappings">
4
+ <mapping directory="$PROJECT_DIR$" vcs="Git" />
5
+ </component>
6
+ </project>
7
+
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm use 1.9.3-p194@crypto_laser --create
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source "http://rubygems.org"
2
+
3
+ gem 'pivotal_git_scripts'
4
+
5
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,34 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ crypto_laser (0.0.3)
5
+ aead
6
+
7
+ GEM
8
+ remote: http://rubygems.org/
9
+ specs:
10
+ aead (1.6.1)
11
+ macaddr (~> 1)
12
+ diff-lcs (1.1.3)
13
+ macaddr (1.6.1)
14
+ systemu (~> 2.5.0)
15
+ pivotal_git_scripts (1.1.4)
16
+ rake (10.0.2)
17
+ rspec (2.12.0)
18
+ rspec-core (~> 2.12.0)
19
+ rspec-expectations (~> 2.12.0)
20
+ rspec-mocks (~> 2.12.0)
21
+ rspec-core (2.12.1)
22
+ rspec-expectations (2.12.0)
23
+ diff-lcs (~> 1.1.3)
24
+ rspec-mocks (2.12.0)
25
+ systemu (2.5.2)
26
+
27
+ PLATFORMS
28
+ ruby
29
+
30
+ DEPENDENCIES
31
+ crypto_laser!
32
+ pivotal_git_scripts
33
+ rake
34
+ rspec
data/README.md ADDED
@@ -0,0 +1,23 @@
1
+ Crypto Laser
2
+ ============
3
+
4
+ Simple library for symmetric authenticated encryption.
5
+
6
+ key = SecureRandom.random_bytes(64)
7
+ cipher_text = CryptoLaser.encrypt(key, "my secret message")
8
+ plain_text = CryptoLaser.decrypt(key, cipher_text)
9
+
10
+ Most of the work is done by the aead gem, which itself relies
11
+ on OpenSSL. Since many users, ourselves included, are on
12
+ OS X, this library uses AES-256-CBC-HMAC-SHA-256 as the cipher
13
+ and MAC.
14
+
15
+ Additional features provided by this library are:
16
+
17
+ - Nonce management. No one knows what a nonce is, so this
18
+ library just takes care of that for you.
19
+ - Base64 encoding of ciphertexts for easy portability.
20
+ - The value returned by encrypt includes the nonce and
21
+ the algorithm used to create the ciphertext. The
22
+ algorithm is authenticated, allowing for later cipher
23
+ suite negotiation should AES-256-CBC prove unreliable.
data/Rakefile ADDED
@@ -0,0 +1,14 @@
1
+ $:.unshift(File.dirname(__FILE__))
2
+ load 'lib/tasks/encrypt.rake'
3
+ load 'lib/tasks/decrypt.rake'
4
+ load 'lib/tasks/generate_key.rake'
5
+
6
+ require 'rspec/core/rake_task'
7
+ desc 'Run specs and features (default)'
8
+ task :default => [:spec]
9
+
10
+ desc "Run specs"
11
+ RSpec::Core::RakeTask.new do |t|
12
+ t.pattern = "./spec/**/*_spec.rb" # don't need this, it's default.
13
+ # Put spec opts in a file named .rspec in root
14
+ end
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "crypto_laser"
6
+ s.version = "0.0.3"
7
+ s.authors = %w(Goodsearch)
8
+ s.email = %w(dev@goodsearch.com)
9
+ s.homepage = "http://www.goodsearch.com"
10
+ s.summary = %q{crypto library}
11
+
12
+ s.files = `git ls-files`.split("\n")
13
+ s.test_files = `git ls-files -- {spec}/*`.split("\n")
14
+ s.require_paths = %w(lib)
15
+ s.required_ruby_version = '>= 1.8.7'
16
+
17
+ s.add_dependency 'aead'
18
+
19
+ s.add_development_dependency "rspec"
20
+ s.add_development_dependency "rake"
21
+
22
+ end
@@ -0,0 +1,52 @@
1
+ require 'aead'
2
+ require 'base64'
3
+
4
+ # Simple library for authenticated encryption. Most of the work
5
+ # is done by the aead gem, which itself punts to OpenSSL.
6
+ #
7
+ # Additional features provided by this library are:
8
+ #
9
+ # - Nonce management. No one knows what a nonce is, so this
10
+ # library just takes of that for you.
11
+ # - Base64 encoding of ciphertexts (since we want to use the
12
+ # encrypted values in config files)
13
+ # - The value returned by encrypt includes the nonce and
14
+ # the algorithm used to create the ciphertext (so we can
15
+ # upgrade to a stronger algorithm later if need be)
16
+
17
+ class CryptoLaser
18
+
19
+ def self.encrypt(key, plain_text)
20
+ code = CryptoLaser.default_algorithm_code
21
+ mode = AEAD::Cipher.new(CryptoLaser.algorithms[code])
22
+ cipher = mode.new(key)
23
+ nonce = CryptoLaser.generate_nonce
24
+ cipher_text = cipher.encrypt(nonce, code, plain_text)
25
+ Base64.strict_encode64(code + nonce + cipher_text).chomp
26
+ end
27
+
28
+ def self.decrypt(key, base64_cipher_text)
29
+ cipher_text = Base64.decode64(base64_cipher_text)
30
+ code = cipher_text[0,2]
31
+ algorithm = CryptoLaser.algorithms[code]
32
+ raise "Invalid algorithm code." unless algorithm
33
+ mode = AEAD::Cipher.new(algorithm)
34
+ cipher = mode.new(key)
35
+ nonce = cipher_text[2...18] # TODO: Base on code
36
+ ctext = cipher_text[18..-1]
37
+ cipher.decrypt(nonce, code, ctext)
38
+ end
39
+
40
+ def self.algorithms
41
+ { "V1" => 'AES-256-CBC-HMAC-SHA-256' }
42
+ end
43
+
44
+ def self.default_algorithm_code
45
+ "V1"
46
+ end
47
+
48
+ def self.generate_nonce
49
+ SecureRandom.random_bytes(16)
50
+ end
51
+
52
+ end
@@ -0,0 +1,8 @@
1
+ require 'crypto_laser'
2
+
3
+ desc "Decrypts standard in to standard out."
4
+ task :decrypt, :keyfile do |t, args|
5
+ key = Base64.decode64(File.read(args[:keyfile]))
6
+ cipher_text = $stdin.read
7
+ puts CryptoLaser.decrypt(key, cipher_text)
8
+ end
@@ -0,0 +1,8 @@
1
+ require 'crypto_laser'
2
+
3
+ desc "Encrypts standard in to standard out."
4
+ task :encrypt, :keyfile do |t, args|
5
+ key = Base64.decode64(File.read(args[:keyfile]))
6
+ plain_text = $stdin.read
7
+ puts CryptoLaser.encrypt(key, plain_text)
8
+ end
@@ -0,0 +1,8 @@
1
+ require 'securerandom'
2
+ require 'base64'
3
+
4
+ desc "Generates a new random key and stores it in a file."
5
+ task :generate_key, :keyfile do |t, args|
6
+ key = SecureRandom.random_bytes(64)
7
+ File.write(args[:keyfile], Base64.strict_encode64(key))
8
+ end
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+
3
+ require 'crypto_laser'
4
+
5
+ describe CryptoLaser do
6
+
7
+ let(:key) { "\"/\\xE0x5\\x9A\\xE9\\x82\\xB8p \\xED^\\xFFX\\xF6\\xB3}\\xB9bR\\xCF\\xDAdH\\xE4\\x9D\\xB5\\xC2r\\x98\\xD3\\xFC\"" }
8
+ let(:nonce) { "\x97\x88\xF3\x0Ei\x84\x99\xC7 OZ2\xCA\v\x873" }
9
+ let(:cipher_text) { "VjGXiPMOaYSZxyBPWjLKC4czENVqZt2Eyj9+h+58kte4cpck4HhanqaFCaSEZL0K2E1WVVn1gPl+at0XAiYj3jd0" }
10
+ let(:plain_text) { "ZOMG PONIES" }
11
+
12
+ describe "#encrypt" do
13
+
14
+ before { described_class.stub(:generate_nonce).and_return nonce }
15
+
16
+ subject { described_class.encrypt(key, plain_text) }
17
+
18
+ it "encrypts plaintext" do
19
+ puts "#{__FILE__}:#{__LINE__} #{key.bytesize}"
20
+ subject.should == cipher_text
21
+ end
22
+ end
23
+
24
+ describe "#decrypt" do
25
+
26
+ subject { described_class.decrypt(key, cipher_text) }
27
+
28
+ it "decrypts cipher text" do
29
+ subject.should == plain_text
30
+ end
31
+
32
+ shared_examples_for "raises because the code is invalid" do
33
+ specify do
34
+ expect { subject }.to raise_error /invalid algorithm code/i
35
+ end
36
+ end
37
+
38
+ context "when the algorithm code is invalid" do
39
+ let(:cipher_text) { Base64.encode64("V2").chomp }
40
+ it_should_behave_like "raises because the code is invalid"
41
+ end
42
+
43
+ context "when the cipher text is too small" do
44
+ let(:cipher_text) { "" }
45
+ it_should_behave_like "raises because the code is invalid"
46
+ end
47
+
48
+ end
49
+
50
+ describe ".generate_nonce" do
51
+
52
+ subject { described_class.generate_nonce }
53
+
54
+ it "should return 16 bytes" do
55
+ subject.bytesize.should == 16
56
+ end
57
+ end
58
+
59
+ end
@@ -0,0 +1,3 @@
1
+ require 'logger'
2
+
3
+
metadata CHANGED
@@ -1,105 +1,114 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: crypto_laser
3
- version: !ruby/object:Gem::Version
4
- prerelease: false
5
- segments:
6
- - 0
7
- - 0
8
- - 2
9
- version: 0.0.2
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
+ prerelease:
10
6
  platform: ruby
11
- authors:
7
+ authors:
12
8
  - Goodsearch
13
9
  autorequire:
14
10
  bindir: bin
15
11
  cert_chain: []
16
-
17
- date: 2012-12-17 00:00:00 -08:00
18
- default_executable:
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
12
+ date: 2012-12-19 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
21
15
  name: aead
22
- prerelease: false
23
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
24
17
  none: false
25
- requirements:
26
- - - ">="
27
- - !ruby/object:Gem::Version
28
- segments:
29
- - 0
30
- version: "0"
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
31
22
  type: :runtime
32
- version_requirements: *id001
33
- - !ruby/object:Gem::Dependency
34
- name: rspec
35
23
  prerelease: false
36
- requirement: &id002 !ruby/object:Gem::Requirement
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rspec
32
+ requirement: !ruby/object:Gem::Requirement
37
33
  none: false
38
- requirements:
39
- - - ">="
40
- - !ruby/object:Gem::Version
41
- segments:
42
- - 0
43
- version: "0"
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
44
38
  type: :development
45
- version_requirements: *id002
46
- - !ruby/object:Gem::Dependency
47
- name: rake
48
39
  prerelease: false
49
- requirement: &id003 !ruby/object:Gem::Requirement
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rake
48
+ requirement: !ruby/object:Gem::Requirement
50
49
  none: false
51
- requirements:
52
- - - ">="
53
- - !ruby/object:Gem::Version
54
- segments:
55
- - 0
56
- version: "0"
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
57
54
  type: :development
58
- version_requirements: *id003
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
59
62
  description:
60
- email:
63
+ email:
61
64
  - dev@goodsearch.com
62
65
  executables: []
63
-
64
66
  extensions: []
65
-
66
67
  extra_rdoc_files: []
67
-
68
- files: []
69
-
70
- has_rdoc: true
71
- homepage: ""
68
+ files:
69
+ - .gitignore
70
+ - .idea/.name
71
+ - .idea/.rakeTasks
72
+ - .idea/crypto_laser.iml
73
+ - .idea/encodings.xml
74
+ - .idea/misc.xml
75
+ - .idea/modules.xml
76
+ - .idea/scopes/scope_settings.xml
77
+ - .idea/vcs.xml
78
+ - .rvmrc
79
+ - Gemfile
80
+ - Gemfile.lock
81
+ - README.md
82
+ - Rakefile
83
+ - crypto_laser.gemspec
84
+ - lib/crypto_laser.rb
85
+ - lib/tasks/decrypt.rake
86
+ - lib/tasks/encrypt.rake
87
+ - lib/tasks/generate_key.rake
88
+ - spec/lib/crypto_laser_spec.rb
89
+ - spec/spec_helper.rb
90
+ homepage: http://www.goodsearch.com
72
91
  licenses: []
73
-
74
92
  post_install_message:
75
93
  rdoc_options: []
76
-
77
- require_paths:
94
+ require_paths:
78
95
  - lib
79
- required_ruby_version: !ruby/object:Gem::Requirement
96
+ required_ruby_version: !ruby/object:Gem::Requirement
80
97
  none: false
81
- requirements:
82
- - - ">="
83
- - !ruby/object:Gem::Version
84
- segments:
85
- - 1
86
- - 9
87
- - 3
88
- version: 1.9.3
89
- required_rubygems_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: 1.8.7
102
+ required_rubygems_version: !ruby/object:Gem::Requirement
90
103
  none: false
91
- requirements:
92
- - - ">="
93
- - !ruby/object:Gem::Version
94
- segments:
95
- - 0
96
- version: "0"
104
+ requirements:
105
+ - - ! '>='
106
+ - !ruby/object:Gem::Version
107
+ version: '0'
97
108
  requirements: []
98
-
99
109
  rubyforge_project:
100
- rubygems_version: 1.3.7
110
+ rubygems_version: 1.8.24
101
111
  signing_key:
102
112
  specification_version: 3
103
113
  summary: crypto library
104
114
  test_files: []
105
-