clearhaus / aes256gcm_decrypt

Decrypt AES256GCM-encrypted data in Apple Pay Payment Tokens.
MIT License
10 stars 1 forks source link

What causes Aes256GcmDecrypt::OpenSSLError: DecryptUpdate failed? #11

Closed tibbon closed 6 years ago

tibbon commented 6 years ago

My use and testing of this gem works locally on my Mac, but all my tests fail on CI with the Aes256GcmDecrypt::OpenSSLError: DecryptUpdate failed error. Any semi-obvious things that could cause that?

mt-clearhaus commented 6 years ago

Hmm, nothing rings a bell, unfortunately. I see in https://github.com/clearhaus/pedicel/issues/8 that you use Ruby 2.3.7, so I have tried running the specs in CircleCI using that version. It was a succes: aes256gcm-decrypt-ruby-2-3-7-in-circle.jpg.gz

Have you tried imitating the specs? E.g. https://github.com/clearhaus/aes256gcm_decrypt/blob/1350f39e715310cfb67be618faff43169323ac5c/spec/decrypt_spec.rb#L5-L18

Otherwise I need more information in order to debug the issue.

tibbon commented 6 years ago

Going to try a few things and loop back in with you. Thanks for much for being quick to respond!

tibbon commented 6 years ago

Hmm, so a few more details. I SSH'd into my CI server, and when I check out this repo and run the tests on there, I get errors consistent with my failing tests on CI otherwise:

u1216@worker-29523161:~/code/aes256gcm_decrypt$ rspec spec
F...FFF

Failures:

  1) Aes256GcmDecrypt::decrypt decrypts correctly
     Failure/Error: plaintext = Aes256GcmDecrypt::decrypt(@ciphertext_and_tag, @key)

     Aes256GcmDecrypt::OpenSSLError:
       DecryptUpdate failed
     # ./spec/decrypt_spec.rb:11:in `decrypt'
     # ./spec/decrypt_spec.rb:11:in `block (2 levels) in <top (required)>'

  2) Aes256GcmDecrypt::decrypt detects tampering with the ciphertext
     Failure/Error:
       expect{Aes256GcmDecrypt::decrypt(@ciphertext_and_tag, @key)}.to \
         raise_error(Aes256GcmDecrypt::AuthenticationError, 'Authentication failed')

       expected Aes256GcmDecrypt::AuthenticationError with "Authentication failed", got #<Aes256GcmDecrypt::OpenSSLError: DecryptUpdate failed> with backtrace:
         # ./spec/decrypt_spec.rb:45:in `decrypt'
         # ./spec/decrypt_spec.rb:45:in `block (3 levels) in <top (required)>'
         # ./spec/decrypt_spec.rb:45:in `block (2 levels) in <top (required)>'
     # ./spec/decrypt_spec.rb:45:in `block (2 levels) in <top (required)>'

  3) Aes256GcmDecrypt::decrypt detects an incorrect tag
     Failure/Error:
       expect{Aes256GcmDecrypt::decrypt(@ciphertext_and_tag, @key)}.to \
         raise_error(Aes256GcmDecrypt::AuthenticationError, 'Authentication failed')

       expected Aes256GcmDecrypt::AuthenticationError with "Authentication failed", got #<Aes256GcmDecrypt::OpenSSLError: DecryptUpdate failed> with backtrace:
         # ./spec/decrypt_spec.rb:51:in `decrypt'
         # ./spec/decrypt_spec.rb:51:in `block (3 levels) in <top (required)>'
         # ./spec/decrypt_spec.rb:51:in `block (2 levels) in <top (required)>'
     # ./spec/decrypt_spec.rb:51:in `block (2 levels) in <top (required)>'

  4) Aes256GcmDecrypt::decrypt detects an incorrect key
     Failure/Error:
       expect{Aes256GcmDecrypt::decrypt(@ciphertext_and_tag, @key)}.to \
         raise_error(Aes256GcmDecrypt::AuthenticationError, 'Authentication failed')

       expected Aes256GcmDecrypt::AuthenticationError with "Authentication failed", got #<Aes256GcmDecrypt::OpenSSLError: DecryptUpdate failed> with backtrace:
         # ./spec/decrypt_spec.rb:57:in `decrypt'
         # ./spec/decrypt_spec.rb:57:in `block (3 levels) in <top (required)>'
         # ./spec/decrypt_spec.rb:57:in `block (2 levels) in <top (required)>'
     # ./spec/decrypt_spec.rb:57:in `block (2 levels) in <top (required)>'

Finished in 0.01616 seconds (files took 0.09075 seconds to load)
7 examples, 4 failures

Failed examples:

rspec ./spec/decrypt_spec.rb:10 # Aes256GcmDecrypt::decrypt decrypts correctly
rspec ./spec/decrypt_spec.rb:43 # Aes256GcmDecrypt::decrypt detects tampering with the ciphertext
rspec ./spec/decrypt_spec.rb:49 # Aes256GcmDecrypt::decrypt detects an incorrect tag
rspec ./spec/decrypt_spec.rb:55 # Aes256GcmDecrypt::decrypt detects an incorrect key

My versions of OpenSSL on CI are different than on my local. On CI (where the tests are failing) I have:

u1216@worker-29523161:~/code/aes256gcm_decrypt$ openssl version
OpenSSL 1.0.1 14 Mar 2012
u1216@worker-29523161:~/code/aes256gcm_decrypt$ ruby -ropenssl -e 'puts OpenSSL::OPENSSL_VERSION'
OpenSSL 1.0.1 14 Mar 2012
u1216@worker-29523161:~/code/aes256gcm_decrypt$ ruby -ropenssl -e 'puts OpenSSL::OPENSSL_LIBRARY_VERSION'
OpenSSL 1.0.1 14 Mar 2012

Locally (MacOS) where it's working I have:

~ ❯❯❯ openssl version
OpenSSL 1.0.2o  27 Mar 2018
~ ❯❯❯ ruby -ropenssl -e 'puts OpenSSL::OPENSSL_VERSION'
OpenSSL 1.0.2o  27 Mar 2018
~ ❯❯❯ ruby -ropenssl -e 'puts OpenSSL::OPENSSL_LIBRARY_VERSION'
OpenSSL 1.0.2o  27 Mar 2018
tibbon commented 6 years ago

I've found the problem that was causing that error.

It seems my CI server was running OpenSSL 1.0.1 14 Mar 2012. I upgraded it to 1.0.2 and it's now fine.

My C-skills aren't great, or I'd put in a PR for this, but I wonder if just checking that OpenSSL is at least 1.0.2 and otherwise raising an error at runtime (or gem compile time) would be good?

mt-clearhaus commented 6 years ago

Thank you very much for reporting the issue -- and even more for finding the cause :smile: :+1:

I will consider adding an OpenSSL version check.