aliquot-pay 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d6ef1cc665eda9098620eba68b1ad54f84fbf95a7451000aed962e955df683bc
4
- data.tar.gz: a6126ced2a1928849052ebed350163990d5f74aff97d26100f54a60189bb092f
3
+ metadata.gz: 44e7c529e137eb8f24695acbee32655f9a1099fb129037ae7a6b7fb9df7eb024
4
+ data.tar.gz: 30134f32f42423d14db49b1ddd3d52d1f9e2efc30c8646ffe64f1ffac199863b
5
5
  SHA512:
6
- metadata.gz: 7ad4156b308d5f0cb263f0ceb2b64db99ec373f073bb71339cb0866812979448345cfee99beddebeaf816cdd38e0d17cb793c39832f366dfa108c9d368a257a8
7
- data.tar.gz: 87a621a3d085c84cec0b393a737a3d05ae5d7afa5b144cfecac0babd1e8ce55d06727428b7fabad9f247c3191a2b26c6ae3369b9c2137e0930d4a9fb8f7ab362
6
+ metadata.gz: 8e8475d0481e3a95fa3211a305645921d07bbd5c50ff5d4e7288a7adbb8974da04fc91c886f3f22d628e5acb1cfc06f988f5203605fd59cdf934b13b1ed54f76
7
+ data.tar.gz: 4057c7276c7ce1f0fb9cc6cdfac418fa1a83a0e2a422570ab61205e49b6d0b19cdbdcd64e8c4612be6c4078af5b2a2448c8210a38a478a74b0e1b76fde46faf0
@@ -11,18 +11,18 @@ module AliquotPay
11
11
  private_key.dh_compute_key(public_key)
12
12
  end
13
13
 
14
- def self.derive_keys(ephemeral_public_key, shared_secret, info)
14
+ def self.derive_keys(ephemeral_public_key, shared_secret, info, length: 32)
15
15
  input_keying_material = ephemeral_public_key + shared_secret
16
16
  if OpenSSL.const_defined?(:KDF) && OpenSSL::KDF.respond_to?(:hkdf)
17
17
  h = OpenSSL::Digest::SHA256.new
18
- hbytes = OpenSSL::KDF.hkdf(input_keying_material, hash: h, salt: '', length: 32, info: info)
18
+ hbytes = OpenSSL::KDF.hkdf(input_keying_material, hash: h, salt: '', length: length * 2, info: info)
19
19
  else
20
- hbytes = HKDF.new(input_keying_material, algorithm: 'SHA256', info: info).next_bytes(32)
20
+ hbytes = HKDF.new(input_keying_material, algorithm: 'SHA256', info: info).next_bytes(length * 2)
21
21
  end
22
22
 
23
23
  {
24
- aes_key: hbytes[0..15],
25
- mac_key: hbytes[16..32],
24
+ aes_key: hbytes[0..length - 1],
25
+ mac_key: hbytes[length..2 * length],
26
26
  }
27
27
  end
28
28
 
data/lib/aliquot-pay.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require 'base64'
2
2
  require 'openssl'
3
+ require 'json'
3
4
 
4
5
  require 'aliquot-pay/util'
5
6
 
@@ -13,23 +14,22 @@ module AliquotPay
13
14
  merchant_id: 'merchant:0123456789',
14
15
  }.freeze
15
16
 
16
- def self.sign(key, encrypted_message)
17
+ def self.sign(key, message)
17
18
  d = OpenSSL::Digest::SHA256.new
18
19
  def key.private?; private_key?; end
19
- Base64.strict_encode64(key.sign(d, encrypted_message))
20
+ Base64.strict_encode64(key.sign(d, message))
20
21
  end
21
22
 
22
- def self.encrypt(cleartext_message, recipient, info = 'Google')
23
+ def self.encrypt(cleartext_message, recipient, cipher, info = 'Google')
23
24
  eph = AliquotPay::Util.generate_ephemeral_key
24
25
  ss = AliquotPay::Util.generate_shared_secret(eph, recipient.public_key)
25
26
 
26
- keys = AliquotPay::Util.derive_keys(eph.public_key.to_bn.to_s(2), ss, info)
27
+ keys = AliquotPay::Util.derive_keys(eph.public_key.to_bn.to_s(2), ss, info, length: cipher.key_len)
27
28
 
28
- c = OpenSSL::Cipher::AES128.new(:CTR)
29
- c.encrypt
30
- c.key = keys[:aes_key]
29
+ cipher.encrypt
30
+ cipher.key = keys[:aes_key]
31
31
 
32
- encrypted_message = c.update(cleartext_message) + c.final
32
+ encrypted_message = cipher.update(cleartext_message) + cipher.final
33
33
 
34
34
  tag = AliquotPay::Util.calculate_tag(keys[:mac_key], encrypted_message)
35
35
 
@@ -72,6 +72,12 @@ module AliquotPay
72
72
  [str.length].pack('V')
73
73
  end
74
74
 
75
+ def self.generate_signature(*args)
76
+ args.map do |s|
77
+ four_byte_length(s) + s
78
+ end.join('')
79
+ end
80
+
75
81
  def self.signature_string(
76
82
  message,
77
83
  recipient_id = DEFAULTS[:merchant_id],
@@ -79,29 +85,46 @@ module AliquotPay
79
85
  protocol_version = 'ECv1'
80
86
  )
81
87
 
82
- four_byte_length(sender_id) +
83
- sender_id +
84
- four_byte_length(recipient_id) +
85
- recipient_id +
86
- four_byte_length(protocol_version) +
87
- protocol_version +
88
- four_byte_length(message) +
89
- message
88
+ generate_signature(sender_id, recipient_id, protocol_version, message)
90
89
  end
91
90
 
92
- # payment:: Google Pay token as a ruby Hash
93
- # signing_key:: OpenSSL::PKEY::EC
94
- # recipient:: OpenSSL::PKey::EC
95
- # encrypted_message:: SignedMessage
96
- def self.generate_token(payment, signing_key, recipient, signed_message = nil)
97
- signed_message ||= JSON.unparse(AliquotPay.encrypt(JSON.unparse(payment), recipient))
98
-
99
- signature_string = AliquotPay.signature_string(signed_message)
91
+ # payment:: Google Pay token as a ruby Hash
92
+ # signing_key:: OpenSSL::PKEY::EC
93
+ # recipient:: OpenSSL::PKey::EC
94
+ # signed_message:: Pass a customized message to sign as signed messaged.
95
+ def self.generate_token_ecv1(payment, signing_key, recipient, signed_message = nil)
96
+ cipher = OpenSSL::Cipher::AES128.new(:CTR)
97
+ signed_message ||= JSON.unparse(encrypt(JSON.unparse(payment), recipient, cipher))
98
+ signature_string = signature_string(signed_message)
100
99
 
101
100
  {
102
101
  'protocolVersion' => 'ECv1',
103
- 'signature' => AliquotPay.sign(signing_key, signature_string),
102
+ 'signature' => sign(signing_key, signature_string),
103
+ 'signedMessage' => signed_message,
104
+ }
105
+ end
106
+
107
+ def self.generate_token_ecv2(payment, signing_key, intermediate_key, recipient, signed_message)
108
+ cipher = OpenSSL::Cipher::AES256.new(:CTR)
109
+ signed_message ||= JSON.unparse(encrypt(JSON.unparse(payment), recipient, cipher))
110
+ signature_string = signature_string(signed_message)
111
+
112
+ signed_key = JSON.unparse(
113
+ 'keyExpiration' => "#{Time.now.to_i + 3600}000",
114
+ 'keyValue' => Base64.strict_encode64(intermediate_key.public_key.to_bn.to_s(2))
115
+ )
116
+
117
+ ik_signature_string = generate_signature('Google', 'ECv2', signed_key)
118
+ signatures = [sign(signing_key, ik_signature_string)]
119
+
120
+ {
121
+ 'protocolVersion' => 'ECv2',
122
+ 'signature' => sign(intermediate_key, signature_string),
104
123
  'signedMessage' => signed_message,
124
+ 'interMediateSigningKey' => {
125
+ 'signedKey' => signed_key,
126
+ 'signatures' => signatures,
127
+ },
105
128
  }
106
129
  end
107
130
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aliquot-pay
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Clearhaus
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-01-08 00:00:00.000000000 Z
11
+ date: 2019-01-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: hkdf