Skip to content
This repository was archived by the owner on Aug 13, 2025. It is now read-only.

Commit 0a4359c

Browse files
dankimioRyan Daigle
authored andcommitted
Use openssl for aes-256-gcm decryption
This lets us drop the (unmaintained) aead dependency, but limits Ruby support to v2.4 and greater. Closes spreedly#11 Closes spreedly#9
1 parent 9abd752 commit 0a4359c

File tree

5 files changed

+36
-41
lines changed

5 files changed

+36
-41
lines changed

.circleci/config.yml

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,15 @@
11
version: 2
22
jobs:
3-
ruby-2.1:
3+
ruby-2.4:
44
docker:
5-
- image: circleci/ruby:2.1.10
5+
- image: circleci/ruby:2.4.4
66
steps:
77
- checkout
88
- run: bundle
99
- run: rake test
10-
ruby-2.2:
10+
ruby-2.5:
1111
docker:
12-
- image: circleci/ruby:2.2.10
13-
steps:
14-
- checkout
15-
- run: bundle
16-
- run: rake test
17-
ruby-2.3:
18-
docker:
19-
- image: circleci/ruby:2.3.7
12+
- image: circleci/ruby:2.5.1
2013
steps:
2114
- checkout
2215
- run: bundle
@@ -25,6 +18,5 @@ workflows:
2518
version: 2
2619
rubies:
2720
jobs:
28-
- ruby-2.1
29-
- ruby-2.2
30-
- ruby-2.3
21+
- ruby-2.4
22+
- ruby-2.5

Gemfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
gemspec
1+
source 'https://rubygems.org'
22

3-
gem 'aead', git: 'https://github.com/Shopify/aead.git', ref: '340e7718d8bd9c1fcf3c443e32f439436ea2b70d'
3+
gemspec

Gemfile.lock

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,24 @@
1-
GIT
2-
remote: https://github.com/Shopify/aead.git
3-
revision: 340e7718d8bd9c1fcf3c443e32f439436ea2b70d
4-
ref: 340e7718d8bd9c1fcf3c443e32f439436ea2b70d
5-
specs:
6-
aead (1.8.2)
7-
macaddr (~> 1)
8-
91
PATH
102
remote: .
113
specs:
12-
gala (0.3.1)
13-
aead (~> 1.8)
4+
gala (0.3.2)
5+
openssl (~> 2.0)
146

157
GEM
168
remote: https://rubygems.org/
179
specs:
18-
macaddr (1.7.1)
19-
systemu (~> 2.6.2)
2010
minitest (5.11.3)
21-
rake (12.0.0)
22-
systemu (2.6.5)
11+
openssl (2.1.0)
12+
rake (12.3.1)
2313

2414
PLATFORMS
2515
ruby
2616

2717
DEPENDENCIES
28-
aead!
2918
bundler (~> 1.14)
3019
gala!
3120
minitest
3221
rake (~> 12.0)
3322

3423
BUNDLED WITH
35-
1.15.4
24+
1.16.1

gala.gemspec

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ Gem::Specification.new do |spec|
1717
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test)/}) }
1818
spec.test_files = `git ls-files -- test/*`.split("\n")
1919
spec.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20-
spec.require_paths = ["lib"]
20+
spec.require_paths = ['lib']
2121

22-
spec.required_ruby_version = ">= 1.8.7"
22+
spec.required_ruby_version = '>= 2.4.0'
2323

24-
spec.add_runtime_dependency 'aead', '~> 1.8'
24+
spec.add_runtime_dependency 'openssl', '~> 2.0'
2525

2626
spec.add_development_dependency 'bundler', '~> 1.14'
2727
spec.add_development_dependency 'rake', '~> 12.0'

lib/gala/payment_token.rb

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
require 'openssl'
22
require 'base64'
3-
require 'aead'
43

54
module Gala
65
class PaymentToken
@@ -111,11 +110,26 @@ def generate_symmetric_key(merchant_id, shared_secret)
111110
end
112111

113112
def decrypt(encrypted_data, symmetric_key)
114-
init_length = 16
115-
init_vector = 0.chr * init_length
116-
mode = ::AEAD::Cipher.new('aes-256-gcm')
117-
cipher = mode.new(symmetric_key, iv_len: init_length)
118-
cipher.decrypt(init_vector, '', encrypted_data)
113+
# Initialization vector of 16 null bytes
114+
iv_length = 16
115+
# 0.chr => "\x00"
116+
iv = 0.chr * iv_length
117+
118+
# Last 16 bytes (iv_length) of encrypted data
119+
tag = encrypted_data[-iv_length..-1]
120+
# Data without tag
121+
encrypted_data = encrypted_data[0..(-iv_length - 1)]
122+
123+
cipher = OpenSSL::Cipher.new("aes-256-gcm").decrypt
124+
cipher.key = symmetric_key
125+
cipher.iv_len = iv_length
126+
cipher.iv = iv
127+
128+
# Decipher without associated authentication data
129+
cipher.auth_tag = tag
130+
cipher.auth_data = ''
131+
132+
cipher.update(encrypted_data) + cipher.final
119133
end
120134
end
121135
end

0 commit comments

Comments
 (0)