potatosalad / erlang-jose

JSON Object Signing and Encryption (JOSE) for Erlang and Elixir
http://hexdocs.pm/jose
MIT License
309 stars 102 forks source link

JWK.block_decrypt error when using RSA-OAEP-256 - A128GCM #66

Closed kdisneur closed 5 years ago

kdisneur commented 5 years ago

Hi,

When we tried to bump from jose 1.8.4 to 1.9.0, some of our tests started to fail with the following message:

     ** (ErlangError) Erlang error: {:crypt_unsupported, [[rsa_padding: :rsa_pkcs1_oaep_padding, rsa_oaep_md: :sha256]]}
     code: |> JOSE.JWK.block_encrypt(%{"alg" => "RSA-OAEP-256", "enc" => "A128GCM"}, jwk)
     stacktrace:
       (jose) src/jose_jwa_unsupported.erl:49: :jose_jwa_unsupported.encrypt_public/3
       (jose) src/jose_jwe_alg_rsa.erl:73: :jose_jwe_alg_rsa.key_encrypt/3
       (jose) src/jose_jwe.erl:296: :jose_jwe.key_encrypt/3
       (jose) src/jose_jwe.erl:204: :jose_jwe.block_encrypt/5

when reading the CHANGELOG, I can see something about fixing some RSA padding:

Extra sanity check for RSA padding modes when falling back.

I guess it might be related but I have no idea how to dig further.

If it can help, I reproduced the error on a separate repository : https://github.com/kdisneur/jose_error

Thanks for your help

victorolinasc commented 5 years ago

I've proposed a fix for this on #67 . I've confirmed it makes the test on your repo pass.

If possible @kdisneur could you check that changing the dep to: {:jose, git: "git@github.com:victorolinasc/erlang-jose.git", branch: "patch-2"} also works for you?

Thanks!

kdisneur commented 5 years ago

I just tried to use your repo and it worked 👍

Thanks for the patch 🙇

victorolinasc commented 5 years ago

Just a heads up: I've just opened a bug report to the OTP team about public_key:decrypt_private/3 not respecting the options passed to it here: so, RSA-OAEP is broken here. Options is ignored.

The fix would be to switch it to use crypto:private_decrypt directly. I'll open another issue to note this, but I thought it'd be good to warn here.

potatosalad commented 5 years ago

@kdisneur @victorolinasc I'm a little late on replying here, but there was a bug prior to 1.9.0 that was not verifying that public_key:decrypt_private/3 (and public_key:encrypt_public/3) were properly respecting the options passed to them instead of just ignoring them.

In other words, if you were using public_key for RSA encryption/decryption operations in OTP 21 or below, you were only ever doing the PKCS#1 Version 1.5 style padding. Even if you passed options that should have used PKCS#1 Version 2.2 OAEP-SHA-1 or OAEP-SHA-256 style padding.

This extra sanity check I added as part of the changes between 1.8.4 and 1.9.0 correctly identifies the bug and will switch back to the pure Erlang implementation of RSA operations from the :jose_jwa_pkcs1 module if :jose.crypto_fallback(true) (or the equivalent application environment variable) is set.

The pure Erlang version is slower. However, it is tested against the OAEP test vectors provided by the RSA security group in pkcs-1v2-1-vec.zip.

The bug filed by @victorolinasc in ERL-878 has been fixed as of OTP 22, but earlier versions will need to use the pure Erlang implementation if RSA OAEP encryption operations are needed.

More comments can be found on #67.