syruppay_jose 1.0.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 50da388cc48fbf6e92b4a745882dcc2b4db070d8
4
+ data.tar.gz: 82593eb5c95b091ce2b36815303a9762f7682ffb
5
+ SHA512:
6
+ metadata.gz: 5d8dcea76f084e244c2d3efd48be45351b803b1d955be3a4c042ef60f315c9e5da194a9b1db7ed8da9def7835ee5c856de0f28cc8ea1009a9d5fb661c193fa44
7
+ data.tar.gz: 8a7fa31b4128d9dd9f236506318a8ad3aff1a694c214562961f9b55f684f7e87f5e2639845f83dc44174f3da7e15d5b4fbe2df2030aaf0ada1d98680193a0c0d
@@ -0,0 +1,12 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ .idea/**
11
+ bin/**
12
+ **/*.iml
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --require spec_helper
3
+ --format=doc
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
4
+ before_install: gem install bundler -v 1.10.6
@@ -0,0 +1,13 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
4
+
5
+ We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion.
6
+
7
+ Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
8
+
9
+ Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.
10
+
11
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
12
+
13
+ This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/)
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in syruppay_jose.gemspec
4
+ gemspec
@@ -0,0 +1,26 @@
1
+ The MIT License
2
+ Copyright (c) 2015 SK PLANET. All Rights Reserved.
3
+
4
+ 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:
5
+
6
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
7
+
8
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS ORIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THEAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHERLIABILITY, 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 INTHE SOFTWARE.
9
+
10
+
11
+ - This software further contains following 3rd-party libraries.
12
+
13
+ Aes_key_wrap library
14
+ This library is Copyright ? 2015 Tom Dalling, but released under the MIT License.
15
+ https://github.com/tomdalling/aes_key_wrap/blob/master/LICENSE.txt
16
+
17
+ Bindata
18
+ This library is copyrighted free software by Dion Mendel, but released under the Ruby License.
19
+ https://github.com/dmendel/bindata/blob/master/COPYING
20
+
21
+ Activesupport
22
+ This library is Copyright ? 2005-2015 David Heinemeier Hansson, but released under the MIT License.. https://github.com/rails/rails/blob/master/activesupport/MIT-LICENSE
23
+
24
+ Url_safe_base64
25
+ This library is Copyright ? 2008 Joe Noon, but released under the MIT License.
26
+ https://github.com/joenoon/url_safe_base64/blob/master/MIT-LICENSE
@@ -0,0 +1,79 @@
1
+ # JOSE for SyrupPay
2
+
3
+ Ruby로 구현한 JOSE(Javascript Object Signing and Encryption) - [RFC 7516](https://tools.ietf.org/html/rfc7516), [RFC 7515](https://tools.ietf.org/html/rfc7515) 규격입니다.
4
+ JOSE 규격은 SyrupPay 결제 데이터 암복호화 및 AccessToken 발행 등에 사용되며 SyrupPay 서비스의 가맹점에 배포하기 위한 목적으로 라이브러리가 구현되었습니다.
5
+
6
+ ## Supported Ruby version
7
+ ~>= Ruby 2.0.0
8
+
9
+ ## Installation
10
+
11
+ ```ruby
12
+ $ gem install syruppay_jose
13
+ ```
14
+
15
+ ## Usage
16
+
17
+ ### JWE
18
+ ```ruby
19
+ require 'syruppay_jose'
20
+
21
+ # SyrupPay가 발급하는 secret
22
+ key = '1234567890123456'
23
+ # JWE header 규격
24
+ # alg : key wrap encryption algorithm. 아래 Supported JOSE encryption algorithms 참조
25
+ # enc : content encryption algorithm. 아래 Supported JOSE encryption algorithms 참조
26
+ # kid : SyrupPay가 발급하는 iss
27
+ header = {:alg=>'A128KW', :enc=>'A128CBC-HS256', :kid=>'syruppay_sample'}
28
+ # 암호화 할 데이터
29
+ payload = '{"iss":"syruppap_sample", "exp":1300819380, "isSample":true}'
30
+
31
+ # encryption and serialize
32
+ jwe_token = SyrupPay::JsonEncryptionCompactSerialization.serialization(key, header, payload)
33
+
34
+ # decryption and deserialize
35
+ actual = SyrupPay::CompactDeserialization.deserialization(key, jwe_token)
36
+ ```
37
+
38
+ ### JWS
39
+ ```ruby
40
+ require 'syruppay_jose'
41
+
42
+ # SyrupPay가 발급하는 secret
43
+ key = '12345678901234561234567890123456'
44
+ # JWS header 규격
45
+ # alg : signature algorithm. 아래 Supported JOSE encryption algorithms 참조
46
+ # kid : SyrupPay가 발급하는 iss
47
+ header = {:alg=>'HS256', :kid=>'syruppay_sample'}
48
+ # sign 할 데이터
49
+ claims = '{"iss":"syruppap_sample", "exp":1300819380, "isSample":true}' #
50
+
51
+ # sign and serialize
52
+ jws_value = SyrupPay::JsonSignatureCompactSerialization.serialization(key, header, claims)
53
+
54
+ # verify and deserialize
55
+ actual = SyrupPay::CompactDeserialization.deserialization(key, jws_value)
56
+ ```
57
+
58
+ ## Supported JOSE encryption algorithms
59
+
60
+ ### "alg" (Algorithm) Header Parameter Values For JWE
61
+ alg Param Value|Key Management Algorithm
62
+ ------|------
63
+ A128KW|AES Key Wrap with default initial value using 128 bit key
64
+ A256KW|AES Key Wrap with default initial value using 256 bit key
65
+
66
+ ### "enc" (Encryption Algorithm) Header Parameter Values for JWE
67
+ enc Param Value|Content Encryption Algorithm
68
+ -------------|------
69
+ A128CBC-HS256|AES_128_CBC_HMAC_SHA_256 authenticated encryption algorithm
70
+
71
+ ### "alg" (Algorithm) Header Parameter Values for JWS
72
+ alg Param Value|Digital Signature or MAC Algorithm
73
+ -----|-------
74
+ HS256|HMAC using SHA-256
75
+
76
+ ## License
77
+
78
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
79
+
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,63 @@
1
+ require 'aes_key_wrap'
2
+ require 'active_support/all'
3
+ require 'jose/jwa/enc/content_encryptionkey_generator'
4
+
5
+ module SyrupPay
6
+ module Jwa
7
+ class AesKeyWrap
8
+ class InvalidKeyLengthError < StandardError; end
9
+
10
+ def initialize(length)
11
+ @length = length
12
+ end
13
+
14
+ def encryption(key, cek)
15
+ valid_key_length!(key, @length)
16
+
17
+ if cek.instance_of? SyrupPay::Jwa::ContentEncryptionKeyGenerator
18
+ kek = cek.generate_random_key
19
+ elsif cek.is_a? String
20
+ kek = cek
21
+ elsif cek.is_a? Array
22
+ kek = cek.pack('C*')
23
+ end
24
+
25
+ key_binary = str_to_binary(key)
26
+ cek_binary = str_to_binary(kek)
27
+
28
+ wrapped_key = AESKeyWrap.wrap(cek_binary, key_binary)
29
+ [kek, wrapped_key]
30
+ end
31
+
32
+ def decryption(key, wrapped_cek)
33
+ key_binary = str_to_binary(key)
34
+ AESKeyWrap.unwrap(wrapped_cek, key_binary)
35
+ end
36
+
37
+ private
38
+ def str_to_binary(str)
39
+ str.unpack('H*').pack('H*')
40
+ end
41
+
42
+ def valid_key_length!(key, length)
43
+ actual_key_len = key.blank? ? 0 : key.try(:bytesize)
44
+ expected_key_len = length
45
+ if expected_key_len != actual_key_len
46
+ raise InvalidKeyLengthError, "JWE key must be #{expected_key_len} bytes. Yours key #{actual_key_len} bytes."
47
+ end
48
+ end
49
+ end
50
+
51
+ class A128Kw < Jwa::AesKeyWrap
52
+ def initialize
53
+ super 16
54
+ end
55
+ end
56
+
57
+ class A256Kw < Jwa::AesKeyWrap
58
+ def initialize
59
+ super 32
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,38 @@
1
+ require 'active_support/security_utils'
2
+ require 'openssl'
3
+ require 'url_safe_base64'
4
+
5
+ module SyrupPay
6
+ module Jwa
7
+ class HmacSha256Signature
8
+ class InvalidKeyLengthError < StandardError; end
9
+ class InvalidVerifyError < StandardError; end
10
+ include ActiveSupport::SecurityUtils
11
+
12
+ def initialize
13
+ @length = 32
14
+ end
15
+
16
+ def sign(key, hmac_data)
17
+ # valid_key_length!(key, @length)
18
+
19
+ OpenSSL::HMAC.digest(OpenSSL::Digest.new('sha256'), key, hmac_data)
20
+ end
21
+
22
+ def verify!(key, hmac_data, expected)
23
+ actual = UrlSafeBase64.encode64(sign(key, hmac_data))
24
+ raise InvalidVerifyError, "expected : #{expected}, actual : #{actual}" unless secure_compare(actual, expected)
25
+ end
26
+
27
+ private
28
+
29
+ def valid_key_length!(key, length)
30
+ actual_key_len = key.blank? ? 0 : key.try(:bytesize)
31
+ expected_key_len = length
32
+ if expected_key_len != actual_key_len
33
+ raise InvalidKeyLengthError, "JWS key must be #{expected_key_len} bytes. Yours key #{actual_key_len} bytes."
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,67 @@
1
+ require 'jose/jwa/enc/content_encryption'
2
+ require 'openssl'
3
+ require 'bindata'
4
+ require 'active_support/security_utils'
5
+ require 'url_safe_base64'
6
+
7
+ module SyrupPay
8
+ module Jwa
9
+ class A128CbcHmac256Encryption < ContentEncryption
10
+ class InvalidVerifyError < StandardError; end
11
+
12
+ include ActiveSupport::SecurityUtils
13
+
14
+ def initialize
15
+ super 32, 16
16
+ end
17
+
18
+ def encrypt_and_sign(cek, iv, payload, aad)
19
+ iv = !iv.nil? ? iv : generate_random_iv
20
+ hmac_key, enc_key = split_key(cek)
21
+
22
+ cipher_text = encryption(enc_key, iv, payload)
23
+ at = sign(hmac_key, iv, cipher_text, aad)
24
+
25
+ [cipher_text, at, iv]
26
+ end
27
+
28
+ def verify_and_decrypt(cek, iv, cipher_text, aad, expected)
29
+ hmac_key, enc_key = split_key(cek)
30
+
31
+ verify_authentication_tag!(hmac_key, iv, cipher_text, aad, expected)
32
+ decryption(enc_key, iv, cipher_text)
33
+ end
34
+
35
+ private
36
+ def encryption(key, iv, payload)
37
+ cipher = OpenSSL::Cipher.new('AES-128-CBC')
38
+ cipher.encrypt
39
+ cipher.key = key
40
+ cipher.iv = iv
41
+ cipher.update(payload)+cipher.final
42
+ end
43
+
44
+ def decryption(key, iv, cipher_text)
45
+ cipher = OpenSSL::Cipher.new('AES-128-CBC')
46
+ cipher.decrypt
47
+ cipher.key = key
48
+ cipher.iv = iv
49
+ cipher.update(cipher_text)+cipher.final
50
+ end
51
+
52
+ def sign(key, iv, cipher_text, aad)
53
+ hmac_data = [aad, iv, cipher_text, BinData::Uint64be.new((aad.length*8)).to_binary_s].join
54
+ OpenSSL::HMAC.digest(OpenSSL::Digest.new('sha256'), key, hmac_data)[0, 16]
55
+ end
56
+
57
+ def verify_authentication_tag!(key, iv, cipher_text, aad, expected)
58
+ actual = UrlSafeBase64.encode64(sign(key, iv, cipher_text, aad))
59
+ raise InvalidVerifyError, "expected : #{expected}, actual : #{actual}" unless secure_compare(actual, expected)
60
+ end
61
+
62
+ def split_key(cek)
63
+ [cek[0, 16], cek[16, 16]]
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,21 @@
1
+ module SyrupPay
2
+ module Jwa
3
+ class ContentEncryption
4
+ include SyrupPay::Jwa::RandomKeyGen
5
+ attr_reader :key_length, :iv_length
6
+
7
+ def initialize(key_length, iv_length)
8
+ @key_length = key_length
9
+ @iv_length = iv_length
10
+ end
11
+
12
+ def generate_random_iv
13
+ randomKey(@iv_length/2)
14
+ end
15
+
16
+ def content_encryption_generator
17
+ SyrupPay::Jwa::ContentEncryptionKeyGenerator.new(@key_length)
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,32 @@
1
+ require 'securerandom'
2
+
3
+ module SyrupPay
4
+ module Jwa
5
+ module RandomKeyGen
6
+ def randomKey(length)
7
+ SecureRandom.hex(length)
8
+ end
9
+ end
10
+
11
+ class ContentEncryptionKeyGenerator
12
+ include SyrupPay::Jwa::RandomKeyGen
13
+ attr_reader :key_length, :cek
14
+
15
+ def initialize(key_length)
16
+ @key_length = key_length
17
+ end
18
+
19
+ def user_encryption_key=(cek)
20
+ @cek = cek
21
+ end
22
+
23
+ def generate_random_key
24
+ if (@cek.nil?)
25
+ @cek = randomKey(@key_length/2)
26
+ end
27
+
28
+ @cek
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,108 @@
1
+ require 'active_support/all'
2
+ require 'jose/jwa/alg/aes_key_wrap'
3
+ require 'jose/jwa/enc/aes128_hmac256_encryption'
4
+ require 'url_safe_base64'
5
+
6
+ module SyrupPay
7
+ module JweSupportAlgorithm
8
+ ALG = [:A128KW, :A256KW]
9
+ ENC = [:'A128CBC-HS256']
10
+
11
+ def alg?(alg)
12
+ ALG.include? alg
13
+ end
14
+
15
+ def enc?(enc)
16
+ ENC.include? enc
17
+ end
18
+
19
+ def keywrap_algorithm?(alg)
20
+ case alg
21
+ when :A128KW then SyrupPay::Jwa::A128Kw.new
22
+ when :A256KW then SyrupPay::Jwa::A256Kw.new
23
+ else nil
24
+ end
25
+ end
26
+
27
+ def encryption_algorithm?(enc)
28
+ case enc
29
+ when :'A128CBC-HS256' then SyrupPay::Jwa::A128CbcHmac256Encryption.new
30
+ else nil
31
+ end
32
+ end
33
+
34
+ def json_to_hash(json)
35
+ ActiveSupport::JSON.decode(json).with_indifferent_access
36
+ end
37
+ end
38
+
39
+ class JweSerializer
40
+ class UnSupportHeaderError < StandardError; end
41
+ class InvalidJweFormatError < StandardError; end
42
+
43
+ include SyrupPay::JweSupportAlgorithm
44
+ attr_accessor :header
45
+ attr_reader :key, :payload
46
+ attr_writer :cek, :iv
47
+
48
+ def initialize(key)
49
+ @key = key
50
+ end
51
+
52
+ def compactSerialize(header = {}, payload)
53
+ @payload = payload
54
+ @header = header.with_indifferent_access
55
+
56
+ validate_header!
57
+
58
+ jwe_alg = keywrap_algorithm? @header[:alg].try(:to_sym)
59
+ jwe_enc = encryption_algorithm? @header[:enc].try(:to_sym)
60
+
61
+ cek_generator = jwe_enc.content_encryption_generator
62
+ cek_generator.user_encryption_key = @cek
63
+ @cek, wrapped_key = jwe_alg.encryption(@key, cek_generator)
64
+
65
+ aad = additional_authenticated_data
66
+ cipher_text, at, @iv = jwe_enc.encrypt_and_sign(@cek, @iv, @payload, aad)
67
+
68
+ [@header.to_json, wrapped_key, @iv, cipher_text, at].collect do |parts|
69
+ UrlSafeBase64.encode64(parts)
70
+ end.join('.')
71
+ end
72
+
73
+ def compactDeserialize(serialized_input)
74
+ validate_deserialize! serialized_input
75
+ header_json, wrapped_key, @iv, cipher_text, at = split_deserialize serialized_input
76
+ @header = json_to_hash(header_json)
77
+
78
+ jwe_alg = keywrap_algorithm? @header[:alg].try(:to_sym)
79
+ jwe_enc = encryption_algorithm? @header[:enc].try(:to_sym)
80
+
81
+ @cek = jwe_alg.decryption(@key, wrapped_key)
82
+
83
+ aad = additional_authenticated_data
84
+ jwe_enc.verify_and_decrypt(@cek, @iv, cipher_text, aad, UrlSafeBase64.encode64(at))
85
+ end
86
+
87
+ private
88
+
89
+ def additional_authenticated_data
90
+ UrlSafeBase64.encode64 header.to_json
91
+ end
92
+
93
+ def validate_header!
94
+ raise UnSupportHeaderError, (header[:alg].presence||'alg(nil)')+' is not supported' unless alg?(header[:alg].try(:to_sym))
95
+ raise UnSupportHeaderError, (header[:enc].presence||'enc(nil)')+' is not supported' unless enc?(header[:enc].try(:to_sym))
96
+ end
97
+
98
+ def validate_deserialize!(src)
99
+ raise InvalidJweFormatError, 'JWE format must be 5 parts' unless src.count('.') == 4
100
+ end
101
+
102
+ def split_deserialize(src)
103
+ src.split('.').collect do |parts|
104
+ UrlSafeBase64.decode64(parts)
105
+ end
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,80 @@
1
+ require 'jose/jwa/alg/hmac_sha256_signature'
2
+ require 'active_support/all'
3
+
4
+ module SyrupPay
5
+ module JwsSupportAlgorithm
6
+ ALG = [:HS256]
7
+
8
+ def alg?(alg)
9
+ ALG.include? alg
10
+ end
11
+
12
+ def signature_algorithm?(alg)
13
+ case alg
14
+ when :HS256 then SyrupPay::Jwa::HmacSha256Signature.new
15
+ else nil
16
+ end
17
+ end
18
+
19
+ def json_to_hash(json)
20
+ ActiveSupport::JSON.decode(json).with_indifferent_access
21
+ end
22
+ end
23
+
24
+ class JwsSerializer
25
+ class UnSupportHeaderError < StandardError; end
26
+ class InvalidJwsFormatError < StandardError; end
27
+
28
+ include SyrupPay::JwsSupportAlgorithm
29
+
30
+ attr_accessor :header
31
+ attr_reader :key, :claims
32
+
33
+ def initialize(key)
34
+ @key = key
35
+ end
36
+
37
+ def compactSerialize(header = {}, claims)
38
+ @claims = claims
39
+ @header = header.with_indifferent_access
40
+
41
+ validate_header!
42
+
43
+ jws_alg = signature_algorithm? @header[:alg].try(:to_sym)
44
+ sign_value = jws_alg.sign(@key, hmac_data)
45
+
46
+ [@header.to_json, claims, sign_value].collect { |parts| UrlSafeBase64.encode64(parts)}.join('.')
47
+ end
48
+
49
+ def compactDeserialize(serialized_input)
50
+ validate_deserialize! serialized_input
51
+
52
+ header_json, @claims, sign_value = split_deserialize serialized_input
53
+ @header = json_to_hash(header_json)
54
+
55
+ jws_alg = signature_algorithm? @header[:alg].try(:to_sym)
56
+ jws_alg.verify!(@key, hmac_data, UrlSafeBase64.encode64(sign_value))
57
+
58
+ @claims
59
+ end
60
+
61
+ private
62
+ def validate_header!
63
+ raise UnSupportHeaderError, (header[:alg].presence||'alg(nil)')+' is not supported' unless alg?(header[:alg].try(:to_sym))
64
+ end
65
+
66
+ def validate_deserialize!(src)
67
+ raise InvalidJwsFormatError, 'JWS format must be 3 parts' unless src.count('.') == 2
68
+ end
69
+
70
+ def split_deserialize(src)
71
+ src.split('.').collect do |parts|
72
+ UrlSafeBase64.decode64(parts)
73
+ end
74
+ end
75
+
76
+ def hmac_data
77
+ [@header.to_json, @claims].collect { |parts| UrlSafeBase64.encode64(parts)}.join('.')
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,5 @@
1
+ module SyrupPay
2
+ module Jose
3
+ VERSION = "1.0.0"
4
+ end
5
+ end
@@ -0,0 +1,55 @@
1
+ require 'jose/version'
2
+ require 'jose/jwe/jwe'
3
+ require 'jose/jws/jws'
4
+ require 'active_support/all'
5
+
6
+ module SyrupPay
7
+ class JsonSignatureCompactSerialization
8
+ def self.serialization(key, header = {}, claims)
9
+ jws_serializer = SyrupPay::JwsSerializer.new(key)
10
+ jws_serializer.compactSerialize(header, claims)
11
+ end
12
+ end
13
+
14
+ class JsonEncryptionCompactSerialization
15
+ def self.serialization(key, header = {}, payload)
16
+ payload = payload
17
+
18
+ jwe_serializer = SyrupPay::JweSerializer.new(key)
19
+ jwe_serializer.compactSerialize(header, payload)
20
+ end
21
+ end
22
+
23
+ class CompactDeserialization
24
+ class UnSupportAlgorithmError < StandardError; end
25
+
26
+ def self.deserialization(key, serialized_src)
27
+ header_json = UrlSafeBase64.decode64(serialized_src.split('.').first)
28
+
29
+ header = json_to_hash(header_json)
30
+
31
+ if (jwe_algorithm?(header[:alg].try(:to_sym)))
32
+ jwe_serializer = SyrupPay::JweSerializer.new(key)
33
+ jwe_serializer.compactDeserialize serialized_src
34
+ elsif (jws_algorithm?(header[:alg].try(:to_sym)))
35
+ jws_serializer = SyrupPay::JwsSerializer.new(key)
36
+ jws_serializer.compactDeserialize serialized_src
37
+ else
38
+ raise UnSupportAlgorithmError, (header[:alg].presence||'alg(nil)')+' is not supported'
39
+ end
40
+ end
41
+
42
+ private
43
+ def self.jwe_algorithm?(alg)
44
+ SyrupPay::JweSupportAlgorithm::ALG.include? alg
45
+ end
46
+
47
+ def self.jws_algorithm?(alg)
48
+ SyrupPay::JwsSupportAlgorithm::ALG.include? alg
49
+ end
50
+
51
+ def self.json_to_hash(json)
52
+ ActiveSupport::JSON.decode(json).with_indifferent_access
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,41 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'jose/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "syruppay_jose"
8
+ spec.version = SyrupPay::Jose::VERSION
9
+ spec.authors = ["placia"]
10
+ spec.email = ["parkgun78@gmail.com"]
11
+
12
+ spec.summary = %q{JOSE for SyrupPay service's merchant}
13
+ spec.description = %q{Library for SyrupPay service's merchant.
14
+ This is implemented JOSE specification, RFC 7515, 7516.
15
+ support algorithm : JWE-A128KW, A256KW, A128CBC-HS256, JWS-HS256}
16
+ spec.homepage = "https://github.com/skplanet/jose-ruby"
17
+ spec.license = "MIT"
18
+
19
+ # Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
20
+ # delete this section to allow pushing this gem to any host.
21
+ # if spec.respond_to?(:metadata)
22
+ # spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com'"
23
+ # else
24
+ # raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
25
+ # end
26
+
27
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
28
+ spec.bindir = "exe"
29
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
30
+ spec.require_paths = ["lib"]
31
+
32
+ spec.required_ruby_version = "~> 2.0"
33
+
34
+ spec.add_development_dependency "bundler", "~> 1.10"
35
+ spec.add_development_dependency "rake", "~> 10.0"
36
+ spec.add_development_dependency "rspec", "~> 3.3"
37
+ spec.add_runtime_dependency "aes_key_wrap", "1.0.1"
38
+ spec.add_runtime_dependency "bindata", "~> 2.1"
39
+ spec.add_runtime_dependency "activesupport", "4.2.4"
40
+ spec.add_runtime_dependency "url_safe_base64", "~> 0.2.2"
41
+ end
metadata ADDED
@@ -0,0 +1,163 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: syruppay_jose
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - placia
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2015-12-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.10'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.10'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.3'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.3'
55
+ - !ruby/object:Gem::Dependency
56
+ name: aes_key_wrap
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '='
60
+ - !ruby/object:Gem::Version
61
+ version: 1.0.1
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '='
67
+ - !ruby/object:Gem::Version
68
+ version: 1.0.1
69
+ - !ruby/object:Gem::Dependency
70
+ name: bindata
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '2.1'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '2.1'
83
+ - !ruby/object:Gem::Dependency
84
+ name: activesupport
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '='
88
+ - !ruby/object:Gem::Version
89
+ version: 4.2.4
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '='
95
+ - !ruby/object:Gem::Version
96
+ version: 4.2.4
97
+ - !ruby/object:Gem::Dependency
98
+ name: url_safe_base64
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 0.2.2
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 0.2.2
111
+ description: |-
112
+ Library for SyrupPay service's merchant.
113
+ This is implemented JOSE specification, RFC 7515, 7516.
114
+ support algorithm : JWE-A128KW, A256KW, A128CBC-HS256, JWS-HS256
115
+ email:
116
+ - parkgun78@gmail.com
117
+ executables: []
118
+ extensions: []
119
+ extra_rdoc_files: []
120
+ files:
121
+ - ".gitignore"
122
+ - ".rspec"
123
+ - ".travis.yml"
124
+ - CODE_OF_CONDUCT.md
125
+ - Gemfile
126
+ - LICENSE.txt
127
+ - README.md
128
+ - Rakefile
129
+ - lib/jose/jwa/alg/aes_key_wrap.rb
130
+ - lib/jose/jwa/alg/hmac_sha256_signature.rb
131
+ - lib/jose/jwa/enc/aes128_hmac256_encryption.rb
132
+ - lib/jose/jwa/enc/content_encryption.rb
133
+ - lib/jose/jwa/enc/content_encryptionkey_generator.rb
134
+ - lib/jose/jwe/jwe.rb
135
+ - lib/jose/jws/jws.rb
136
+ - lib/jose/version.rb
137
+ - lib/syruppay_jose.rb
138
+ - syruppay_jose.gemspec
139
+ homepage: https://github.com/skplanet/jose-ruby
140
+ licenses:
141
+ - MIT
142
+ metadata: {}
143
+ post_install_message:
144
+ rdoc_options: []
145
+ require_paths:
146
+ - lib
147
+ required_ruby_version: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - "~>"
150
+ - !ruby/object:Gem::Version
151
+ version: '2.0'
152
+ required_rubygems_version: !ruby/object:Gem::Requirement
153
+ requirements:
154
+ - - ">="
155
+ - !ruby/object:Gem::Version
156
+ version: '0'
157
+ requirements: []
158
+ rubyforge_project:
159
+ rubygems_version: 2.4.8
160
+ signing_key:
161
+ specification_version: 4
162
+ summary: JOSE for SyrupPay service's merchant
163
+ test_files: []