Reputation: 1002
Lately a piece of code broke and I realised that my calls to OpenSSL::HMAC.hexdigest('SHA1', Rails.application.key_generator.generate_key('abcdef123456'), 'something')
generated different output on different machine running the function.
I originally though this was due to a change in OpenSSL, but running OpenSSL::HMAC.hexdigest('SHA1', 'abcdef123', 'something')
lead to the same result on all machines.
Turns out that Rails.application.key_generator.generate_key('abcdef123456')
returns different values on different machines.
Running locally, I obtain a different results that on the server.
Same Ruby version, same Rails version, the only difference is the platform (x86_64-darwin21 vs x86_64-linux).
Shouldn't Rails.application.key_generator.generate_key
always return the same results?
Otherwise the code will break if it migrates to another machine.
Upvotes: 1
Views: 407
Reputation: 10536
I have tested this in three different Linux distributions, each using a different version of OpenSSL. I am unable to reproduce the issue that you have described.
You said that there were two commands that you ran:
OpenSSL::HMAC.hexdigest('SHA1', 'abcdef123', 'something')
which you said returned the same value on every machineOpenSSL::HMAC.hexdigest('SHA1', Rails.application.key_generator.generate_key('abcdef123456'), 'something')
which you said returned different values on each machineI believe that the cause of the latter returning different values is that each machine is using a different secret_key_base
value. The only unique element of generate_key
is @secret
which is the value of Rails.application.secret_key_base
.
I recommend that you double-check:
RAILS_ENV
)secret_key_base
value for that environmentThe only way that I've been able to get different values for each is to change the secret_key_env
value. This value is set automatically in test
and development
environments and can be set in a variety of ways for other environments. You can check the value in the Rails console with Rails.application.secret_key_base
.
Below you can find the steps to validate that different versions of OpenSSL have no impact on the value generated.
docker run -it alpine:3.17.0 sh
apk add build-base libc6-compat openssl openssl-dev readline readline-dev tzdata zlib zlib-dev
wget https://cache.ruby-lang.org/pub/ruby/3.1/ruby-3.1.3.tar.gz && tar xvf ruby-3.1.3.tar.gz && cd ruby-3.1.3 && ./configure --with-openssl-dir=/usr && make && make install
openssl version
# OpenSSL 3.0.7 1 Nov 2022 (Library: OpenSSL 3.0.7 1 Nov 2022)
ruby -ropenssl -e 'puts OpenSSL::OPENSSL_VERSION; puts OpenSSL::OPENSSL_VERSION_NUMBER'
# OpenSSL 3.0.7 1 Nov 2022
# 805306480
cd /
gem install rails
rails new foo --skip-git --skip-keeps --skip-mailer --skip-mailbox --skip-text --skip-active-record --skip-active-job --skip-active-storage --skip-action-cable --skip-asset-pipeline --skip-javascript --skip-hotwire --skip-jbuilder --skip-test --skip-system-test --api --minimal
cd foo
export RAILS_ENV=production
export SECRET_KEY_BASE="eedfd5f234fbca535134ae551981d319df449c096c9bcd041b01ef77b7810eb4e480a7671c2b8788adb8782f950e9684ff582c5135d76ff088795d284f5917ff"
rails console
OpenSSL::HMAC.hexdigest('SHA1', Rails.application.key_generator.generate_key('abcdef123456'), 'something')
=> "f1ba53b65a27d443ae8bc60fcc248230c651032f"
docker run -it alpine:3.16.3 sh
apk add build-base libc6-compat openssl openssl-dev readline readline-dev tzdata zlib zlib-dev
wget https://cache.ruby-lang.org/pub/ruby/3.1/ruby-3.1.3.tar.gz && tar xvf ruby-3.1.3.tar.gz && cd ruby-3.1.3 && ./configure --with-openssl-dir=/usr && make && make install
openssl version
# OpenSSL 1.1.1s 1 Nov 2022
ruby -ropenssl -e 'puts OpenSSL::OPENSSL_VERSION; puts OpenSSL::OPENSSL_VERSION_NUMBER'
# OpenSSL 1.1.1s 1 Nov 2022
# 269488447
cd /
gem install rails
rails new foo --skip-git --skip-keeps --skip-mailer --skip-mailbox --skip-text --skip-active-record --skip-active-job --skip-active-storage --skip-action-cable --skip-asset-pipeline --skip-javascript --skip-hotwire --skip-jbuilder --skip-test --skip-system-test --api --minimal
cd foo
export RAILS_ENV=production
export SECRET_KEY_BASE="eedfd5f234fbca535134ae551981d319df449c096c9bcd041b01ef77b7810eb4e480a7671c2b8788adb8782f950e9684ff582c5135d76ff088795d284f5917ff"
rails console
OpenSSL::HMAC.hexdigest('SHA1', Rails.application.key_generator.generate_key('abcdef123456'), 'something')
=> "f1ba53b65a27d443ae8bc60fcc248230c651032f"
docker run -it debian:11.5 sh
apt update && apt install -y build-essential libreadline-dev libreadline8 openssl libssl-dev tzdata wget zlib1g zlib1g-dev
wget https://cache.ruby-lang.org/pub/ruby/3.1/ruby-3.1.3.tar.gz && tar xvf ruby-3.1.3.tar.gz && cd ruby-3.1.3 && ./configure --with-openssl-dir=/usr && make && make install
openssl version
# OpenSSL 1.1.1n 15 Mar 2022
ruby -ropenssl -e 'puts OpenSSL::OPENSSL_VERSION; puts OpenSSL::OPENSSL_VERSION_NUMBER'
# OpenSSL 1.1.1n 15 Mar 2022
# 269488367
cd /
gem install rails
rails new foo --skip-git --skip-keeps --skip-mailer --skip-mailbox --skip-text --skip-active-record --skip-active-job --skip-active-storage --skip-action-cable --skip-asset-pipeline --skip-javascript --skip-hotwire --skip-jbuilder --skip-test --skip-system-test --api --minimal
cd foo
export RAILS_ENV=production
export SECRET_KEY_BASE="eedfd5f234fbca535134ae551981d319df449c096c9bcd041b01ef77b7810eb4e480a7671c2b8788adb8782f950e9684ff582c5135d76ff088795d284f5917ff"
rails console
OpenSSL::HMAC.hexdigest('SHA1', Rails.application.key_generator.generate_key('abcdef123456'), 'something')
=> "f1ba53b65a27d443ae8bc60fcc248230c651032f"
Upvotes: 2