Skip to content

RSA JWK parsing #523

Closed
Closed
@bellebaum

Description

@bellebaum

This came up while reworking the JWK stuff for #520

The function create_rsa_key for OpenSSL version 3 looks like this:

ASN1_SEQUENCE = %i[n e d p q dp dq qi].freeze
def create_rsa_key(rsa_parameters)
sequence = ASN1_SEQUENCE.each_with_object([]) do |key, arr|
next if rsa_parameters[key].nil?
arr << OpenSSL::ASN1::Integer.new(rsa_parameters[key])
end
if sequence.size > 2 # For a private key
sequence.unshift(OpenSSL::ASN1::Integer.new(0))
end
OpenSSL::PKey::RSA.new(OpenSSL::ASN1::Sequence(sequence).to_der)
end

I like the approach of converting a JWK to DER, then feeding it into OpenSSL, since this is unlikely to change (in fact, wouldn't this work for other versions of OpenSSL, making all the "legacy" implementations unnecessary?)

Anyways, the code has a few problems.

Firstly, any subset of parameters specified in ASN1_SEQUENCE could be present in an illformed JWK, and the resulting DER can then probably not be parsed by any SSL library.

But secondly, there is an important missmatch between RFC 7518, Section 6.3.2

The parameter "d" is REQUIRED for RSA private keys. The others enable optimizations and SHOULD be included by producers of JWKs representing RSA private keys. If the producer includes any of the other private key parameters, then all of the others MUST be present, with the exception of "oth", which MUST only be present when more than two prime factors were used.

and RFC 3447, Appendix A.1.2, which only permits keys with all parameters present.
This implies that valid JWKs containing exactly the kty specific keys kty, n, e, and d, are not guaranteed to be parseable this way.

One could try to calculate the missing values, but especially the step of finding p and q is not trivial at all...

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions