OpenSSL::PKey interface has changed in Ruby 2.4
cmoylan opened this issue · 10 comments
The attributes e
, n
, d
, etc are no longer directly accessible. Those attributes are now set through setter functions:
https://ruby-doc.org/stdlib-2.4.1/libdoc/openssl/rdoc/OpenSSL/PKey/RSA.html#method-i-set_key
https://ruby-doc.org/stdlib-2.4.1/libdoc/openssl/rdoc/OpenSSL/PKey/RSA.html#method-i-set_factors
https://ruby-doc.org/stdlib-2.4.1/libdoc/openssl/rdoc/OpenSSL/PKey/RSA.html#method-i-set_crt_params
I had a pull request #44 to update JWK#to_rsa_key
but it breaks for versions of Ruby < 2.4. The simplest solution is to check the OpenSSL
version before attempting to set the key attributes. If you don't have any objections or a better solution, I'm happy to submit a PR with the change.
Even under ruby 2.4.1, I can execute this code.
e = 'AQAB'
n = 'xT8fom6CyF90d4FaipIZuYD6jC7Eie6JpPAAgKy7qWjzzG-Aof9_ULPFabxMGP_M4Y83iV8dI8swEI4dfkY8zzgLfvZIcwOOy6KQvdWQcas8rrLMTkeT2pfY-abG1awvuz3aEpaibia1-UF80IvYHPpr6_4b5YAPQ3LF4WZHd1gEvQ1WC-rBiWbmVIC-MSIMeQHGISM0SVxa-p3LtsQGbgb0VsaTSbWHHCwKAfLdYLmrOh0bGEtC0aZoAmoBMefEw7FVTQmyBHiJtnuZ7oPGjSMGlP1DSfa6GkUYw-qA7OBoJaYAzZiboIiUyAkPQE5QiBipW-DIoiBzUn_n12fIhw'
key = OpenSSL::PKey::RSA.new
key.e = OpenSSL::BN.new(UrlSafeBase64.decode64(e), 2)
key.n = OpenSSL::BN.new(UrlSafeBase64.decode64(n), 2)
puts key.to_pem
FYI: my ruby, openssl, openssl gem versions are here.
nov@tov json-jwt (master)$ pry
[1] pry(main)> require 'openssl'
=> true
[2] pry(main)> RUBY_VERSION
=> "2.4.1"
[3] pry(main)> OpenSSL::OPENSSL_VERSION
=> "OpenSSL 1.0.2k 26 Jan 2017"
[4] pry(main)> OpenSSL::VERSION
=> "2.0.3"
That's odd. If I run the specs for the gem on 2.4.1 I get a bunch of failures with:
Failure/Error: key.e = e
NoMethodError:
undefined method `e=' for #<OpenSSL::PKey::RSA:0x007fba39cb1858>
Did you mean? e
For the time being, I'll stay on 2.3 which doesn't cause any issues. I wonder why I have problems on 2.4 and you don't. I was on MRI 2.4.1, installed through RVM.
Checking Ruby version is't sufficient.
You need to check your OpenSSL::OPENSSL_VERSION
(it also can be confirmed via openssl version
in your terminal), and OpenSSL::VERSION
too.
Since my local MacBook and travis server passes the specs, I guess your machine have buggy version of them.
https://travis-ci.org/nov/json-jwt/jobs/217231907
ps.
If you are familiar with C, you can confirm the methods are defined here.
https://github.com/ruby/openssl/blob/master/ext/openssl/ossl_pkey_rsa.c#L735
Ok, thank you.
I'm not sure why this was closed, but when running the same setup as @nov, I'm getting a large number of deprecation warnings on these methods.
/usr/local/var/rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/json-jwt-1.7.1/lib/json/jwk.rb:105: warning: #e= is deprecated; use #set_key
/usr/local/var/rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/json-jwt-1.7.1/lib/json/jwk.rb:106: warning: #n= is deprecated; use #set_key
/usr/local/var/rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/json-jwt-1.7.1/lib/json/jwk.rb:107: warning: #d= is deprecated; use #set_key
/usr/local/var/rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/json-jwt-1.7.1/lib/json/jwk.rb:108: warning: #p= is deprecated; use #set_factors
/usr/local/var/rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/json-jwt-1.7.1/lib/json/jwk.rb:109: warning: #q= is deprecated; use #set_factors
/usr/local/var/rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/json-jwt-1.7.1/lib/json/jwk.rb:110: warning: #dmp1= is deprecated; use #set_crt_params
/usr/local/var/rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/json-jwt-1.7.1/lib/json/jwk.rb:111: warning: #dmq1= is deprecated; use #set_crt_params
/usr/local/var/rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/json-jwt-1.7.1/lib/json/jwk.rb:112: warning: #iqmp= is deprecated; use #set_crt_params
Everything still works, but clearly these methods are going to be deprecated. The initial suggestion of switching on the version of OpenSSL might still be a good one?
which version of openssl gem and openssl otself are you using?
As you mentioned in your post, here's the output in my local:
[1] pry(main)> require 'openssl'
=> true
[2] pry(main)> RUBY_VERSION
=> "2.4.1"
[3] pry(main)> OpenSSL::OPENSSL_VERSION
=> "OpenSSL 1.0.2k 26 Jan 2017"
[4] pry(main)> OpenSSL::VERSION
=> "2.0.3"
I get the same output when running those lines in irb
, as well as when running those lines in rails console
.
I don't see any of the warnings (or exceptions) when running the example that you posted here: #45 (comment)
So I can't really explain it yet. I'm seeing the warnings when running the tests for a fork of https://github.com/nsarno/knock where I've integrated json-jwt
for supporting JWKs. You can clone the repo and run the tests with rake test
on the support_jwks_keys
branch:
https://github.com/bitmaker-internal/knock/tree/support_jwks_keys
Let me know if you need me to dig further!
Ah, I found it.
ruby/openssl@7ea72f1#diff-915017dbfe6a2e8cd9741502cfe8f759
Beauty! Nice sleuthing!