最近一段代码坏了,我意识到我对OpenSSL::HMAC.hexdigest('SHA1', Rails.application.key_generator.generate_key('abcdef123456'), 'something')
的调用在不同的机器上运行该函数产生了不同的输出。
我原本以为这是由于OpenSSL的变化,但是在所有机器上运行OpenSSL::HMAC.hexdigest('SHA1', 'abcdef123', 'something')
导致相同的结果。
结果显示Rails.application.key_generator.generate_key('abcdef123456')
在不同的机器上返回不同的值。
在本地运行,我得到的结果与在服务器上不同。
相同的Ruby版本,相同的Rails版本,唯一的区别是平台(x86_64-darwin21 vs x86_64-linux)。
不应该Rails.application.key_generator.generate_key
总是返回相同的结果?
否则,如果代码迁移到另一台机器,将会中断。
我在三个不同的Linux发行版中进行了测试,每个发行版都使用不同版本的OpenSSL。我无法重现您所描述的问题。
你说你运行了两个命令:
OpenSSL::HMAC.hexdigest('SHA1', 'abcdef123', 'something')
,你说在每台机器上返回相同的值OpenSSL::HMAC.hexdigest('SHA1', Rails.application.key_generator.generate_key('abcdef123456'), 'something')
,你说在每台机器上返回不同的值
我认为后者返回不同值的原因是每台机器使用不同的secret_key_base
值。generate_key
唯一的唯一元素是@secret
,即Rails.application.secret_key_base
的值。
我建议你仔细检查:
- 每台机器都在相同的环境中运行(
RAILS_ENV
) - 每台机器都使用相同的
secret_key_base
值
我能够获得不同值的唯一方法是更改secret_key_env
值。该值在test
和development
环境中自动设置,在其他环境中可以通过多种方式设置。您可以在Rails控制台中使用Rails.application.secret_key_base
检查该值。
下面是验证不同版本的OpenSSL对生成的值没有影响的步骤。
Alpine 3.17.0和OpenSSL 3.0.7
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"
Alpine 3.16.3和OpenSSL 1.1.1
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"
Debian 11.5和OpenSSL 1.1.1n
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"