jwt_nacl 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ad2b78d24e6d521e31f3c32794553484c053fec8
4
+ data.tar.gz: 558da9dbdb8ff7503d69864e1d4e35c65a855ed4
5
+ SHA512:
6
+ metadata.gz: c8de2dc24a3557ae69b88c97e57e34a6d9257a8e40a756f65beb678936c109edc4469ce469fb707a64abc119633811c5f7f413a69473e9245571fe59df983f3f
7
+ data.tar.gz: ade53f2ea0edf4f97e193b69f6c661bd53334fce46fd588730ffcfb5cabe0d729902a9d3c127024eba573a0353388a7fa8c63816640d58a762632f55da9dc019
@@ -0,0 +1,36 @@
1
+ https://raw.githubusercontent.com/github/gitignore/master/Ruby.gitignore
2
+
3
+ *.gem
4
+ *.rbc
5
+ /.config
6
+ /coverage/
7
+ /InstalledFiles
8
+ /pkg/
9
+ /spec/reports/
10
+ /spec/examples.txt
11
+ /test/tmp/
12
+ /test/version_tmp/
13
+ /tmp/
14
+
15
+ # Used by dotenv library to load environment variables.
16
+ # .env
17
+
18
+ ## Documentation cache and generated files:
19
+ /.yardoc/
20
+ /_yardoc/
21
+ /doc/
22
+ /rdoc/
23
+
24
+ ## Environment normalization:
25
+ /.bundle/
26
+ /vendor/bundle
27
+ /lib/bundler/man/
28
+
29
+ # for a library or gem, you might want to ignore these files since the code is
30
+ # intended to run in multiple environments; otherwise, check them in:
31
+ # Gemfile.lock
32
+ # .ruby-version
33
+ # .ruby-gemset
34
+
35
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
36
+ .rvmrc
@@ -0,0 +1,7 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.2.6
5
+ - 2.3.3
6
+ - 2.4.0
7
+ before_install: gem install bundler -v 1.13.7
@@ -0,0 +1,6 @@
1
+ ## Changelog
2
+
3
+ ### v0.1.0 (2017-01-29)
4
+
5
+ * Initial
6
+ * support Edwards-curve Digital Signature Algorithm (EdDSA) using Curve25519
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in jwt_nacl.gemspec
4
+ gemspec
@@ -0,0 +1,50 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ jwt_nacl (0.1.0)
5
+ rbnacl (~> 4.0)
6
+ rbnacl-libsodium (~> 1.0)
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ ansi (1.5.0)
12
+ builder (3.2.3)
13
+ docile (1.1.5)
14
+ ffi (1.9.17)
15
+ json (2.0.3)
16
+ minitest (5.10.1)
17
+ minitest-reporters (1.1.14)
18
+ ansi
19
+ builder
20
+ minitest (>= 5.0)
21
+ ruby-progressbar
22
+ rake (12.0.0)
23
+ rbnacl (4.0.1)
24
+ ffi
25
+ rbnacl-libsodium (1.0.11)
26
+ rbnacl (>= 3.0.1)
27
+ ruby-progressbar (1.8.1)
28
+ simplecov (0.13.0)
29
+ docile (~> 1.1.0)
30
+ json (>= 1.8, < 3)
31
+ simplecov-html (~> 0.10.0)
32
+ simplecov-html (0.10.0)
33
+ wwtd (1.3.0)
34
+ yard (0.9.8)
35
+
36
+ PLATFORMS
37
+ ruby
38
+
39
+ DEPENDENCIES
40
+ bundler (~> 1.13)
41
+ jwt_nacl!
42
+ minitest (~> 5.0)
43
+ minitest-reporters (~> 1.1)
44
+ rake (~> 12.0)
45
+ simplecov (~> 0.13)
46
+ wwtd (~> 1.3)
47
+ yard (~> 0.9)
48
+
49
+ BUNDLED WITH
50
+ 1.13.7
@@ -0,0 +1,9 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 Gary Fleshman
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,117 @@
1
+ # JWT NaCl [![travis][ci_img]][travis] [![yard docs][yd_img]][yard_docs] [![code climate][cc_img]][code_climate]
2
+
3
+ ## A JSON Web Token (JWT) implementation using NaCl cryptography
4
+
5
+ ### Description
6
+ A Ruby JSON Web Token implementation using Edwards-curve Digital Signature Algorithm ([EdDSA][eddsa]) [curve Ed25519 digital signatures][ed25519] from the state-of-the-art NaCl [Networking and Cryptography library][nacl] by [Daniel J. Bernstein][bernstein].
7
+
8
+ ## Installation
9
+
10
+ Add this line to your application's Gemfile:
11
+
12
+ ```ruby
13
+ gem 'jwt_nacl'
14
+ ```
15
+
16
+ And then execute:
17
+
18
+ $ bundle
19
+
20
+ Or install it directly as:
21
+
22
+ $ gem install jwt_nacl
23
+
24
+ ### Philosophy & Design Goals
25
+ * Convention over configuration
26
+ * Use of state-of-the-art cryptography, including EdDSA Curve25519 elliptic curves
27
+ * Minimal API surface area
28
+ * Thorough test coverage
29
+ * Modularity for comprehension and extensibility
30
+
31
+ ### Why NaCl?
32
+ Cryptography typically exposes a high degree of complexity, due to many possible configuration decisions. One poor choice could result in an insecure system.
33
+
34
+ NaCl is different. NaCl provides an expertly-assembled, high-level cryptographic API with the correct configuration already built-in. See [RbNaCl][rbnacl] for more rationale.
35
+
36
+ For a more conventional JWT implementation, please refer to the related [json_web_token](https://github.com/garyf/json_web_token) gem.
37
+
38
+ ## Usage
39
+
40
+ ### JWT.sign(claims, private_key)
41
+
42
+ #### Returns a 3 element hash that includes:
43
+ * a JSON Web Token
44
+ * the private key
45
+ * the public key
46
+
47
+ `claims` (required) hash (non-empty)
48
+
49
+ `private_key` (optional) string, 32 random byte signing key
50
+
51
+ Example
52
+
53
+ ```ruby
54
+ require 'jwt_nacl'
55
+
56
+ claims = {iss: "mike", exp: 1300819380, :"http://example.com/is_root" => false}
57
+
58
+ private_hex = "d2c5c54bc205266f12a8a21809aa2989536959f666a5d68710e6fab94674041a"
59
+ private_key = [private_hex].pack("H*")
60
+
61
+ public_hex = "1e10af4b79b8d005c8b4237161f1350844b2e6c1a8d6aa4817151c04a2751731"
62
+ public_key = [public_hex].pack("H*")
63
+
64
+ # Sign with an elliptical curve Ed25519 digital signature
65
+ jwt = JWT.sign(claims, private_key)
66
+ #=> {
67
+ jwt: "eyJhbGciOiJFZDI1NTE5IiwidHlwIjoiSldUIn0.eyJpc3MiOiJtaWtlIiwiZXhwIjoxMzAwODE5MzgwLCJodHRwOi8vZXhhbXBsZS5jb20vaXNfcm9vdCI6ZmFsc2V9.f2y6Sax9eK9M3JiFCt4ZfzzOL56SWNhydHpPPIoVkm21D3_bJq5DmFLgH8ee2OlzSlZMoq009jLSg6AC0mn4DA",
68
+ private_key: private_key,
69
+ public_key: public_key
70
+ }
71
+ ```
72
+
73
+ ### JWT.verify(jwt, public_key)
74
+
75
+ #### Returns a hash:
76
+ * \{claims: < JWT claims set >\}, if the digital signature is verified
77
+ * \{error: "invalid"\}, otherwise
78
+
79
+ `jwt` (required) is a JSON web token string
80
+
81
+ `public_key` (required) string, 32 byte verifying key
82
+
83
+ Example
84
+
85
+ ```ruby
86
+ require 'jwt_nacl'
87
+
88
+ jwt = "eyJhbGciOiJFZDI1NTE5IiwidHlwIjoiSldUIn0.eyJpc3MiOiJtaWtlIiwiZXhwIjoxMzAwODE5MzgwLCJodHRwOi8vZXhhbXBsZS5jb20vaXNfcm9vdCI6ZmFsc2V9.f2y6Sax9eK9M3JiFCt4ZfzzOL56SWNhydHpPPIoVkm21D3_bJq5DmFLgH8ee2OlzSlZMoq009jLSg6AC0mn4DA"
89
+
90
+ hex = "1e10af4b79b8d005c8b4237161f1350844b2e6c1a8d6aa4817151c04a2751731"
91
+ public_key = [hex].pack("H*")
92
+
93
+ # Verify with an elliptical curve Ed25519 public key
94
+ JWT.verify(jwt, public_key)
95
+ #=> {
96
+ claims: {iss: "mike", exp: 1300819380, :"http://example.com/is_root" => false}
97
+ }
98
+ ```
99
+
100
+ ### Supported encryption algorithm
101
+ Ed25519, Edwards-curve Digital Signature Algorithm (EdDSA) using Curve25519
102
+
103
+ ### Supported Ruby versions
104
+ Ruby 2.2.6 and up
105
+
106
+ [eddsa]: https://en.wikipedia.org/wiki/EdDSA
107
+ [ed25519]: http://ed25519.cr.yp.to/
108
+ [nacl]: http://nacl.cr.yp.to/
109
+ [bernstein]: https://en.wikipedia.org/wiki/Daniel_J._Bernstein
110
+
111
+ [rbnacl]: https://github.com/cryptosphere/rbnacl/blob/master/README.md
112
+ [travis]: https://travis-ci.org/garyf/jwt_nacl
113
+ [ci_img]: https://travis-ci.org/garyf/jwt_nacl.svg?branch=master
114
+ [yard_docs]: http://www.rubydoc.info/github/garyf/jwt_nacl
115
+ [yd_img]: http://img.shields.io/badge/yard-docs-blue.svg
116
+ [code_climate]: https://codeclimate.com/github/garyf/jwt_nacl
117
+ [cc_img]: https://codeclimate.com/github/garyf/jwt_nacl/badges/gpa.svg
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
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
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "jwt_nacl"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,38 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'jwt_nacl/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "jwt_nacl"
8
+ spec.version = JwtNacl::VERSION
9
+ spec.authors = ["Gary Fleshman"]
10
+ spec.email = ["gfleshman@newforge-tech.com"]
11
+
12
+ spec.summary = "JSON Web Token (JWT) for Ruby using NaCl cryptography"
13
+ spec.description = <<-HERE
14
+ A Ruby JSON Web Token implementation using NaCl Ed25519 digital signatures from the
15
+ state-of-the-art networking and cryptography library by Daniel J. Bernstein.
16
+ HERE
17
+ spec.homepage = "https://github.com/garyf/jwt_nacl"
18
+ spec.license = "MIT"
19
+
20
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
21
+ f.match(%r{^(test|spec|features)/})
22
+ end
23
+ spec.bindir = "exe"
24
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
25
+ spec.require_paths = ["lib"]
26
+ spec.required_ruby_version = ">= 2.2.6"
27
+
28
+ spec.add_runtime_dependency "rbnacl", "~> 4.0"
29
+ spec.add_runtime_dependency "rbnacl-libsodium", "~> 1.0"
30
+
31
+ spec.add_development_dependency "bundler", "~> 1.13"
32
+ spec.add_development_dependency "minitest", "~> 5.0"
33
+ spec.add_development_dependency "minitest-reporters", "~> 1.1"
34
+ spec.add_development_dependency "rake", "~> 12.0"
35
+ spec.add_development_dependency "simplecov", "~> 0.13"
36
+ spec.add_development_dependency "yard", "~> 0.9"
37
+ spec.add_development_dependency "wwtd", "~> 1.3"
38
+ end
@@ -0,0 +1,64 @@
1
+ require "jwt_nacl/jws"
2
+ require "jwt_nacl/util"
3
+
4
+ # Encode claims for transmission as a JSON object that is used as the payload
5
+ # of a JSON Web Signature (JWS) structure, enabling the claims
6
+ # to be integrity protected with a signature for later verification
7
+ # @see http://tools.ietf.org/html/rfc7519
8
+ module JwtNacl
9
+ module_function
10
+
11
+ # @param claims [Hash] input for a digital signature computation
12
+ # @param private_key [String] 32 random bytes (optional)
13
+ # @return [Hash] a hash with a signed jwt, private_key, and public_key
14
+ # @example
15
+ # claims = {iss: "mike", exp: 1300819380, :"http://example.com/is_root" => false}
16
+ # private_hex = "d2c5c54bc205266f12a8a21809aa2989536959f666a5d68710e6fab94674041a"
17
+ # private_key = [private_hex].pack("H*")
18
+ # public_hex = "1e10af4b79b8d005c8b4237161f1350844b2e6c1a8d6aa4817151c04a2751731"
19
+ # public_key = [public_hex].pack("H*")
20
+ # JwtNacl.sign(claims, private_key)
21
+ # # => {jwt: "eyJhbGciOiJFZDI1NTE5IiwidHlwIjoiSldUIn0.eyJpc3MiOiJtaWtlIiwiZXhwIjoxMzAwODE5MzgwLCJodHRwOi8vZXhhbXBsZS5jb20vaXNfcm9vdCI6ZmFsc2V9.f2y6Sax9eK9M3JiFCt4ZfzzOL56SWNhydHpPPIoVkm21D3_bJq5DmFLgH8ee2OlzSlZMoq009jLSg6AC0mn4DA", private_key: private_key, public_key: public_key}
22
+ def sign(claims, private_key = nil)
23
+ Jws.sign(validated_payload(claims), private_key)
24
+ end
25
+
26
+ # @param jwt [String] a JSON Web Token
27
+ # @param public_key [String] 32 byte verifying key
28
+ # @return [Hash] +{claims: < the jwt claims set hash >}+ if the jwt verifies,
29
+ # or +{error: "invalid"}+ otherwise
30
+ # @example
31
+ # jwt = "eyJhbGciOiJFZDI1NTE5IiwidHlwIjoiSldUIn0.eyJpc3MiOiJtaWtlIiwiZXhwIjoxMzAwODE5MzgwLCJodHRwOi8vZXhhbXBsZS5jb20vaXNfcm9vdCI6ZmFsc2V9.f2y6Sax9eK9M3JiFCt4ZfzzOL56SWNhydHpPPIoVkm21D3_bJq5DmFLgH8ee2OlzSlZMoq009jLSg6AC0mn4DA"
32
+ # hex = "1e10af4b79b8d005c8b4237161f1350844b2e6c1a8d6aa4817151c04a2751731"
33
+ # public_key = [hex].pack("H*")
34
+ # JwtNacl.verify(jwt, public_key)
35
+ # # => {claims: {iss: "mike", exp: 1300819380, :"http://example.com/is_root" => false}}
36
+ def verify(jwt, public_key)
37
+ verified_claims(Jws.verify(jwt, public_key))
38
+ end
39
+
40
+ def validated_payload(claims)
41
+ raise("invalid claims") if !claims || claims.empty? || !claims.is_a?(Hash)
42
+ claims.to_json
43
+ end
44
+
45
+ def verified_claims(hsh)
46
+ return {error: "invalid"} if hsh[:error]
47
+ {claims: decoded_claims(hsh[:jwt].split(".")[1])}
48
+ end
49
+
50
+ def decoded_claims(str)
51
+ Util.symbolize_keys(
52
+ JSON.parse(
53
+ Base64Url.decode(str)
54
+ )
55
+ )
56
+ end
57
+
58
+ private_class_method :validated_payload,
59
+ :verified_claims,
60
+ :decoded_claims
61
+ end
62
+
63
+ # alias
64
+ JWT = JwtNacl
@@ -0,0 +1,42 @@
1
+ require "base64"
2
+
3
+ module JwtNacl
4
+ # Provide base64url encoding and decoding functions without padding, based upon standard
5
+ # base64 encoding and decoding functions that do use padding
6
+ # @see http://tools.ietf.org/html/rfc7515#appendix-C
7
+ module Base64Url
8
+ module_function
9
+
10
+ # @param str [String]
11
+ # @return [String] a urlsafe_encode64 string with all trailing "=" padding removed
12
+ # @example
13
+ # Base64Url.encode("foo")
14
+ # # => "Zm9v"
15
+ def encode(str)
16
+ base64_padding_removed(Base64.urlsafe_encode64(str))
17
+ end
18
+
19
+ # @param str [String] encoded as url_encode64
20
+ # @return [String] with trailing "=" padding added before decoding
21
+ # @example
22
+ # Base64Url.decode("YmFy")
23
+ # # => "bar"
24
+ def decode(str)
25
+ Base64.urlsafe_decode64(base64_padding_added(str))
26
+ end
27
+
28
+ def base64_padding_removed(encoded)
29
+ encoded.gsub(/[=]/, "")
30
+ end
31
+
32
+ def base64_padding_added(str)
33
+ mod = str.length % 4
34
+ return str if mod == 0
35
+ raise("Invalid base64 string") if mod == 1
36
+ "#{str}#{"=" * (4 - mod)}"
37
+ end
38
+
39
+ private_class_method :base64_padding_removed,
40
+ :base64_padding_added
41
+ end
42
+ end
@@ -0,0 +1,45 @@
1
+ require "rbnacl/libsodium"
2
+ require "rbnacl"
3
+
4
+ module JwtNacl
5
+ # Sign or verify JSON Web Signature (JWS) signing input using Edwards-curve
6
+ # Digital Signature Algorithm (EdDSA) curve Ed25519
7
+ # @see https://ed25519.cr.yp.to/
8
+ module Ed25519
9
+ module_function
10
+
11
+ # @param message [String] input payload for a digital signature computation
12
+ # @param seed [String] 32 random bytes (optional)
13
+ # @return [Hash] a hash with the private_key, public_key, and signature
14
+ # @example
15
+ # Ed25519.sign(message, seed)
16
+ # # => {private_key: private_key, public_key: public_key, signature: signature}
17
+ def sign(message, seed = nil)
18
+ signing_key = seed ? RbNaCl::SigningKey.new(seed) : RbNaCl::SigningKey.generate
19
+ {
20
+ private_key: signing_key.to_bytes,
21
+ public_key: signing_key.verify_key.to_bytes,
22
+ signature: signing_key.sign(message)
23
+ }
24
+ end
25
+
26
+ # @param public_key [String] 32 byte key used to authenticate a digital signature
27
+ # @param signature [String] alleged signature to be checked
28
+ # @param message [String] message to be authenticated
29
+ # @return [String, Boolean] verified message or false
30
+ # @example
31
+ # Ed25519.verify(public_key, signature, message)
32
+ # # => message
33
+ def verify(public_key, signature, message)
34
+ verify_key(public_key, signature, message)
35
+ message
36
+ rescue
37
+ false
38
+ end
39
+
40
+ def verify_key(public_key, signature, message)
41
+ RbNaCl::VerifyKey.new(public_key)
42
+ .verify(signature, message)
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,58 @@
1
+ require "jwt_nacl/base64_url"
2
+ require "jwt_nacl/ed25519"
3
+
4
+ module JwtNacl
5
+ # Represent content to be secured with digital signatures
6
+ # @see http://tools.ietf.org/html/rfc7515
7
+ module Jws
8
+ HEADER = {
9
+ alg: "Ed25519",
10
+ typ: "JWT"
11
+ }
12
+ JWS_PARTS = 3
13
+
14
+ module_function
15
+
16
+ # @param payload [String] input for a digital signature computation
17
+ # @param private_key [String] 32 random bytes (optional)
18
+ # @return [Hash] a hash with a signed jwt, private_key, and public_key
19
+ # @example
20
+ # Jws.sign(payload, private_key)
21
+ # # => {jwt: jwt, private_key: private_key, public_key: public_key}
22
+ def sign(payload, private_key = nil)
23
+ signing_input = encode_input(payload)
24
+ hsh = Ed25519.sign(signing_input, private_key)
25
+ {
26
+ jwt: "#{signing_input}.#{Base64Url.encode(hsh[:signature])}",
27
+ private_key: hsh[:private_key],
28
+ public_key: hsh[:public_key]
29
+ }
30
+ end
31
+
32
+ # @param jwt [String] input to be authenticated
33
+ # @param public_key [String] 32 byte key used to authenticate a digital signature
34
+ # @return [Hash] a hash with a verified jwt (e.g. jwt: jwt) or not verified (e.g. error: "invalid")
35
+ # @example
36
+ # Jws.verify(jwt, public_key)
37
+ # # => {jwt: jwt}
38
+ def verify(jwt, public_key)
39
+ verified?(jwt, public_key) ? {jwt: jwt} : {error: "invalid"}
40
+ end
41
+
42
+ def encode_input(payload)
43
+ "#{Base64Url.encode(HEADER.to_json)}.#{Base64Url.encode(payload)}"
44
+ end
45
+
46
+ def verified?(jwt, public_key)
47
+ ary = jwt.split(".")
48
+ return unless ary.length == JWS_PARTS
49
+ signature = Base64Url.decode(ary[2])
50
+ message = "#{ary[0]}.#{ary[1]}"
51
+
52
+ Ed25519.verify(public_key, signature, message)
53
+ end
54
+
55
+ private_class_method :encode_input,
56
+ :verified?
57
+ end
58
+ end
@@ -0,0 +1,34 @@
1
+ require "rbnacl/libsodium"
2
+ require "rbnacl"
3
+
4
+ module JwtNacl
5
+ # Utility methods
6
+ module Util
7
+ ED25519_SEEDBYTES = 32
8
+
9
+ module_function
10
+
11
+ def ed25519_random_seed
12
+ RbNaCl::Random.random_bytes(ED25519_SEEDBYTES)
13
+ end
14
+
15
+ # @param hsh [Hash]
16
+ # @return [Hash] a new hash with all keys converted to symbols,
17
+ # provided that they respond to .to_sym
18
+ # @example
19
+ # Util.symbolize_keys({"a" => 0, "b" => "2", c: "3"})
20
+ # # => {a: 0, b: "2", c: "3"}
21
+ # @see cf. rails activesupport/lib/active_support/core_ext/hash/keys.rb
22
+ def symbolize_keys(hsh)
23
+ transform_keys(hsh) { |key| key.to_sym rescue key }
24
+ end
25
+
26
+ def transform_keys(hsh)
27
+ result = Hash.new
28
+ hsh.keys.each { |k| result[yield(k)] = hsh[k] }
29
+ result
30
+ end
31
+
32
+ private_class_method :transform_keys
33
+ end
34
+ end
@@ -0,0 +1,3 @@
1
+ module JwtNacl
2
+ VERSION = "0.1.0"
3
+ end
metadata ADDED
@@ -0,0 +1,189 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jwt_nacl
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Gary Fleshman
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-01-29 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rbnacl
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '4.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '4.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rbnacl-libsodium
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.13'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.13'
55
+ - !ruby/object:Gem::Dependency
56
+ name: minitest
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '5.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '5.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: minitest-reporters
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.1'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.1'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rake
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '12.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '12.0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: simplecov
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '0.13'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '0.13'
111
+ - !ruby/object:Gem::Dependency
112
+ name: yard
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '0.9'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '0.9'
125
+ - !ruby/object:Gem::Dependency
126
+ name: wwtd
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '1.3'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '1.3'
139
+ description: |2
140
+ A Ruby JSON Web Token implementation using NaCl Ed25519 digital signatures from the
141
+ state-of-the-art networking and cryptography library by Daniel J. Bernstein.
142
+ email:
143
+ - gfleshman@newforge-tech.com
144
+ executables: []
145
+ extensions: []
146
+ extra_rdoc_files: []
147
+ files:
148
+ - ".gitignore"
149
+ - ".travis.yml"
150
+ - CHANGELOG.md
151
+ - Gemfile
152
+ - Gemfile.lock
153
+ - LICENSE.md
154
+ - README.md
155
+ - Rakefile
156
+ - bin/console
157
+ - bin/setup
158
+ - jwt_nacl.gemspec
159
+ - lib/jwt_nacl.rb
160
+ - lib/jwt_nacl/base64_url.rb
161
+ - lib/jwt_nacl/ed25519.rb
162
+ - lib/jwt_nacl/jws.rb
163
+ - lib/jwt_nacl/util.rb
164
+ - lib/jwt_nacl/version.rb
165
+ homepage: https://github.com/garyf/jwt_nacl
166
+ licenses:
167
+ - MIT
168
+ metadata: {}
169
+ post_install_message:
170
+ rdoc_options: []
171
+ require_paths:
172
+ - lib
173
+ required_ruby_version: !ruby/object:Gem::Requirement
174
+ requirements:
175
+ - - ">="
176
+ - !ruby/object:Gem::Version
177
+ version: 2.2.6
178
+ required_rubygems_version: !ruby/object:Gem::Requirement
179
+ requirements:
180
+ - - ">="
181
+ - !ruby/object:Gem::Version
182
+ version: '0'
183
+ requirements: []
184
+ rubyforge_project:
185
+ rubygems_version: 2.6.8
186
+ signing_key:
187
+ specification_version: 4
188
+ summary: JSON Web Token (JWT) for Ruby using NaCl cryptography
189
+ test_files: []