tonglian-ruby-sdk 0.2.0 → 0.3.1
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.
- checksums.yaml +4 -4
- data/lib/tonglian-ruby-sdk.rb +38 -12
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 34e702fea8cfb17cedcc44ca1c3cef1c047b43c35d96904b3e1dd07c5e8ada72
|
4
|
+
data.tar.gz: b432d9015bf5dba98ef5921f42b7e742d2440c42487d4919cce2d7cec24c67f0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b2e90a848ff85e07a0689df84c5eb07a6cf01426b7a6b23d4414cd51011306afc509b39557f1d321726a569abeb4453af05035e14ca0f99dfc6d85c58499d069
|
7
|
+
data.tar.gz: 520cc51c2a2a1933d377e16ec83cdbae62e756a2dc33d7defa744c244b0d061acfd7f3645e88fd2351c694cb3cbe38be0a448abe6254b2ec9aef0cc17ff75993
|
data/lib/tonglian-ruby-sdk.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# to avoid error when loading PKCS12 private key file
|
2
|
-
|
2
|
+
current_dir = File.dirname(__FILE__)
|
3
|
+
provider_conf = File.join(current_dir, 'add-openssl-provider.conf')
|
4
|
+
ENV['OPENSSL_CONF'] = provider_conf
|
3
5
|
|
4
6
|
require 'openssl'
|
5
7
|
require 'cgi'
|
@@ -33,7 +35,6 @@ module TonglianRubySdk
|
|
33
35
|
data['sign'] = @signer.sign(data)
|
34
36
|
|
35
37
|
url = URI(@api_end_point)
|
36
|
-
|
37
38
|
http = Net::HTTP.new(url.host, url.port)
|
38
39
|
http.use_ssl = true if @api_end_point.downcase.starts_with?('https') # Enable SSL for HTTPS
|
39
40
|
|
@@ -42,9 +43,9 @@ module TonglianRubySdk
|
|
42
43
|
request.body = URI.encode_www_form(data)
|
43
44
|
response = http.request(request)
|
44
45
|
|
45
|
-
|
46
|
-
|
47
|
-
|
46
|
+
object = JSON.parse(response.body)
|
47
|
+
@signer.verify?(object) || raise('Invalid response signature!')
|
48
|
+
{ 'code' => response.code, 'data' => object }
|
48
49
|
end
|
49
50
|
|
50
51
|
private
|
@@ -65,25 +66,26 @@ module TonglianRubySdk
|
|
65
66
|
end
|
66
67
|
|
67
68
|
def sign(params)
|
68
|
-
|
69
|
+
message = make_sign_message(params)
|
69
70
|
rsa = OpenSSL::PKey::RSA.new private_key
|
70
|
-
Base64.strict_encode64(rsa.sign(
|
71
|
+
Base64.strict_encode64(rsa.sign(OpenSSL::Digest.new('SHA256'), message))
|
71
72
|
end
|
72
73
|
|
73
74
|
def verify?(params, signature = nil)
|
74
75
|
signature = params['sign'] if signature.nil? || signature.to_s.empty?
|
75
|
-
|
76
|
+
params.delete('sign')
|
77
|
+
message = make_verify_message(params)
|
78
|
+
|
76
79
|
public_file = File.open(@public_path)
|
77
80
|
public_key = OpenSSL::X509::Certificate.new(public_file).public_key.export
|
78
81
|
rsa = OpenSSL::PKey::RSA.new(public_key)
|
79
|
-
rsa.verify('
|
82
|
+
rsa.verify(OpenSSL::Digest.new('SHA256'), Base64.decode64(signature), message)
|
80
83
|
end
|
81
84
|
|
82
85
|
private
|
83
86
|
|
84
87
|
def private_key
|
85
88
|
return @private_key if @private_key
|
86
|
-
|
87
89
|
private_file = File.open(@private_path)
|
88
90
|
@private_key = OpenSSL::PKCS12.new(private_file, @private_passwd).key.export
|
89
91
|
end
|
@@ -100,11 +102,35 @@ module TonglianRubySdk
|
|
100
102
|
params.keys.sort.map do |k|
|
101
103
|
next if %w[sign signType].include? k
|
102
104
|
next if params[k].nil? || params[k].to_s.empty?
|
103
|
-
|
105
|
+
|
104
106
|
sorted_params.push("#{k}=#{params[k]}")
|
105
107
|
end
|
106
108
|
|
107
|
-
|
109
|
+
flattened_params = sorted_params.join('&')
|
110
|
+
md5_digest = Digest::MD5.digest(flattened_params)
|
111
|
+
Base64.strict_encode64(md5_digest)
|
112
|
+
end
|
113
|
+
|
114
|
+
def make_verify_message(params)
|
115
|
+
params = sort_object(params)
|
116
|
+
flattened_params = params.to_json
|
117
|
+
Base64.strict_encode64(Digest::MD5.digest(flattened_params))
|
118
|
+
end
|
119
|
+
|
120
|
+
# In Ruby 3, a hash preserves the order the keys are inserted
|
121
|
+
# So we can make a 'sorted' hash and generate a sorted json later
|
122
|
+
def sort_object(obj)
|
123
|
+
result = nil
|
124
|
+
if obj.is_a? Hash
|
125
|
+
result = {}
|
126
|
+
obj.keys.sort.each { |k| result[k] = sort_object(obj[k]) }
|
127
|
+
elsif obj.is_a? Array
|
128
|
+
result = []
|
129
|
+
obj.sort.each { |k| result.push(k) }
|
130
|
+
else
|
131
|
+
result = obj
|
132
|
+
end
|
133
|
+
result
|
108
134
|
end
|
109
135
|
end
|
110
136
|
end
|