netpayclient 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/lib/netpayclient/version.rb +1 -1
- data/lib/netpayclient.rb +109 -107
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 32c3909cc8ec5db2b3009059574bc91c6733602e
|
4
|
+
data.tar.gz: c33527542332eed2a9983ff5fb84ddf74f50062b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 352035e63a04e75ac656c266eeeb7c3053966ff9a20ae5953c36955934da43b0887a11ae3f6e3a1347ae50ffad8d55861e91adc71cbfe8d0a5e4edad4767b2f3
|
7
|
+
data.tar.gz: d9778fc97ca42a68aa7f61c1f710005f18d1af8a28a1b631b4da3d811c93625b5dbc106073fd3a7bb055691165ba532fda39d9b0cb4f1ea7c975cb0522d9d359
|
data/README.md
CHANGED
@@ -38,7 +38,7 @@ netpay.sign_order(merid, ordno, amount, curyid, transdate, transtype)
|
|
38
38
|
netpay.verify(plain, checkvalue)
|
39
39
|
```
|
40
40
|
|
41
|
-
###
|
41
|
+
### 应答数据的签名验证包装 verify_trans_response
|
42
42
|
```ruby
|
43
43
|
netpay.verify_trans_response(merid, ordno, amount, curyid, transdate, transtype, ordstatus, check)
|
44
44
|
```
|
data/lib/netpayclient/version.rb
CHANGED
data/lib/netpayclient.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require "netpayclient/version"
|
2
2
|
|
3
|
-
|
3
|
+
module Netpayclient
|
4
4
|
require 'openssl'
|
5
5
|
|
6
6
|
DES_KEY = 'SCUBEPGW'
|
@@ -27,11 +27,15 @@ class Netpayclient
|
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
-
def self.
|
30
|
+
def self.build_key(path: nil, hash: {})
|
31
|
+
Netpayclient.new(path: path, hash: hash)
|
32
|
+
end
|
33
|
+
|
34
|
+
def hex2bin(hexdata)
|
31
35
|
[hexdata].pack "H*"
|
32
36
|
end
|
33
37
|
|
34
|
-
def
|
38
|
+
def padstr(src, len=256, chr='0', d='L')
|
35
39
|
src.strip!
|
36
40
|
case d
|
37
41
|
when 'L'
|
@@ -41,41 +45,41 @@ class Netpayclient
|
|
41
45
|
end
|
42
46
|
end
|
43
47
|
|
44
|
-
def
|
45
|
-
|
48
|
+
def bin2int(bindata)
|
49
|
+
bchexdec(bindata.unpack('H*')[0])
|
46
50
|
end
|
47
51
|
|
48
|
-
def
|
52
|
+
def bchexdec(hexdata)
|
49
53
|
hexdata.to_i(16)
|
50
54
|
end
|
51
55
|
|
52
|
-
def
|
56
|
+
def bcdechex(decdata)
|
53
57
|
decdata.to_s(16)
|
54
58
|
end
|
55
59
|
|
56
|
-
def
|
60
|
+
def sha1_128(string)
|
57
61
|
require 'digest/sha1'
|
58
62
|
hash = Digest::SHA1.hexdigest(string)
|
59
|
-
sha_bin =
|
60
|
-
sha_pad =
|
63
|
+
sha_bin = hex2bin(hash)
|
64
|
+
sha_pad = hex2bin(HASH_PAD)
|
61
65
|
sha_pad + sha_bin
|
62
66
|
end
|
63
67
|
|
64
|
-
def
|
68
|
+
def mybcpowmod(num, pow, mod)
|
65
69
|
num.to_bn.mod_exp(pow, mod)
|
66
70
|
end
|
67
71
|
|
68
|
-
def
|
69
|
-
p =
|
70
|
-
q =
|
71
|
-
u =
|
72
|
-
dP =
|
73
|
-
dQ =
|
74
|
-
c =
|
72
|
+
def rsa_encrypt(private_key, input)
|
73
|
+
p = bin2int(private_key[:prime1])
|
74
|
+
q = bin2int(private_key[:prime2])
|
75
|
+
u = bin2int(private_key[:coefficient])
|
76
|
+
dP = bin2int(private_key[:prime_exponent1])
|
77
|
+
dQ = bin2int(private_key[:prime_exponent2])
|
78
|
+
c = bin2int(input)
|
75
79
|
cp = c % p
|
76
80
|
cq = c % q
|
77
|
-
a =
|
78
|
-
b =
|
81
|
+
a = mybcpowmod(cp, dP, p)
|
82
|
+
b = mybcpowmod(cq, dQ, q)
|
79
83
|
if a > b
|
80
84
|
result = a - b
|
81
85
|
else
|
@@ -87,102 +91,100 @@ class Netpayclient
|
|
87
91
|
result = result % p
|
88
92
|
result = result * q
|
89
93
|
result = result + b
|
90
|
-
ret =
|
91
|
-
ret =
|
94
|
+
ret = bcdechex(result)
|
95
|
+
ret = padstr(ret).upcase
|
92
96
|
ret.size == 256 ? ret : false
|
93
97
|
end
|
94
98
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
99
|
+
class Netpayclient
|
100
|
+
def initialize(path: nil, hash: {})
|
101
|
+
require 'iniparse'
|
102
|
+
@private_key = {}
|
103
|
+
if path
|
104
|
+
config_hash = IniParse.parse(File.read(path))['NetPayClient']
|
105
|
+
else
|
106
|
+
config_hash = hash
|
107
|
+
end
|
108
|
+
hex = ""
|
109
|
+
if not config_hash['MERID'].nil?
|
110
|
+
ret = config_hash['MERID']
|
111
|
+
@private_key[:MERID] = ret
|
112
|
+
hex = config_hash['prikeyS'][80...config_hash['prikeyS'].size]
|
113
|
+
elsif not config_hash['PGID'].nil?
|
114
|
+
ret = config_hash['PGID']
|
115
|
+
@private_key[:PGID] = ret
|
116
|
+
hex = config_hash['pubkeyS'][48...config_hash['pubkeyS'].size]
|
117
|
+
else
|
118
|
+
raise 'config error'
|
119
|
+
end
|
120
|
+
bin = hex2bin(hex)
|
121
|
+
@private_key[:modulus] = bin[0,128]
|
122
|
+
|
123
|
+
prime1 = bin[384,64]
|
124
|
+
enc = Crypto.decrypt(prime1)
|
125
|
+
@private_key[:prime1] = enc
|
126
|
+
prime2 = bin[448,64]
|
127
|
+
enc = Crypto.decrypt(prime2)
|
128
|
+
@private_key[:prime2] = enc
|
129
|
+
prime_exponent1 = bin[512,64]
|
130
|
+
enc = Crypto.decrypt(prime_exponent1)
|
131
|
+
@private_key[:prime_exponent1] = enc
|
132
|
+
prime_exponent2 = bin[576,64]
|
133
|
+
enc = Crypto.decrypt(prime_exponent2)
|
134
|
+
@private_key[:prime_exponent2] = enc
|
135
|
+
coefficient = bin[640,64]
|
136
|
+
enc = Crypto.decrypt(coefficient)
|
137
|
+
@private_key[:coefficient] = enc
|
118
138
|
end
|
119
|
-
bin = self.class.hex2bin(hex)
|
120
|
-
@private_key[:modulus] = bin[0,128]
|
121
|
-
|
122
|
-
prime1 = bin[384,64]
|
123
|
-
enc = Crypto.decrypt(prime1)
|
124
|
-
@private_key[:prime1] = enc
|
125
|
-
prime2 = bin[448,64]
|
126
|
-
enc = Crypto.decrypt(prime2)
|
127
|
-
@private_key[:prime2] = enc
|
128
|
-
prime_exponent1 = bin[512,64]
|
129
|
-
enc = Crypto.decrypt(prime_exponent1)
|
130
|
-
@private_key[:prime_exponent1] = enc
|
131
|
-
prime_exponent2 = bin[576,64]
|
132
|
-
enc = Crypto.decrypt(prime_exponent2)
|
133
|
-
@private_key[:prime_exponent2] = enc
|
134
|
-
coefficient = bin[640,64]
|
135
|
-
enc = Crypto.decrypt(coefficient)
|
136
|
-
@private_key[:coefficient] = enc
|
137
|
-
end
|
138
139
|
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
140
|
+
def rsa_decrypt(input)
|
141
|
+
check = bchexdec(input)
|
142
|
+
modulus = bin2int(@private_key[:modulus])
|
143
|
+
exponent = bchexdec("010001")
|
144
|
+
result = mybcpowmod(check, exponent, modulus)
|
145
|
+
rb = bcdechex(result)
|
146
|
+
padstr(rb).upcase
|
147
|
+
end
|
147
148
|
|
148
|
-
|
149
|
-
|
150
|
-
|
149
|
+
def sign(msg)
|
150
|
+
if not @private_key.key?(:MERID)
|
151
|
+
return false
|
152
|
+
end
|
153
|
+
hb = sha1_128(msg)
|
154
|
+
return rsa_encrypt(@private_key, hb)
|
151
155
|
end
|
152
|
-
hb = self.class.sha1_128(msg)
|
153
|
-
return self.class.rsa_encrypt(@private_key, hb)
|
154
|
-
end
|
155
156
|
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
157
|
+
def sign_order(merid, ordno, amount, curyid, transdate, transtype)
|
158
|
+
return false if (merid.size!=15)
|
159
|
+
return false if (ordno.size!=16)
|
160
|
+
return false if (amount.size!=12)
|
161
|
+
return false if (curyid.size!=3)
|
162
|
+
return false if (transdate.size!=8)
|
163
|
+
return false if (transtype.size!=4)
|
164
|
+
plain = merid + ordno + amount + curyid + transdate + transtype
|
165
|
+
return sign(plain)
|
166
|
+
end
|
166
167
|
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
168
|
+
def verify(plain, check)
|
169
|
+
return false if not @private_key.key?(:PGID)
|
170
|
+
return false if check.size != 256
|
171
|
+
hb = sha1_128(plain)
|
172
|
+
hbhex = hb.unpack('H*')[0].upcase
|
173
|
+
rbhex = rsa_decrypt(check)
|
174
|
+
return hbhex == rbhex ? true : false
|
175
|
+
end
|
175
176
|
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
177
|
+
def verify_trans_response(merid, ordno, amount, curyid, transdate, transtype, ordstatus, check)
|
178
|
+
return false if (merid.size!=15)
|
179
|
+
return false if (ordno.size!=16)
|
180
|
+
return false if (amount.size!=12)
|
181
|
+
return false if (curyid.size!=3)
|
182
|
+
return false if (transdate.size!=8)
|
183
|
+
return false if (transtype.size!=4)
|
184
|
+
return false if (ordstatus.size!=4)
|
185
|
+
return false if (check.size!=256)
|
186
|
+
plain = merid + ordno + amount + curyid + transdate + transtype + ordstatus
|
187
|
+
return verify(plain, check)
|
188
|
+
end
|
187
189
|
end
|
188
190
|
end
|