Subject: Re: [jose] backwards compatibility attack on JWT impls (was: I-D Action: draft-ietf-jose-json-web-algorithms-02.txt)

From: "Vladimir Dzhuvinov / NimbusDS" <[email-masked]>
Date: Mon, 25 Mar 2013 07:02:00 -0700

Hi guys,

Just checked in a simple counter measure as suggested below, should
become part of the new release, probably sometime later this week.

https://bitbucket.org/nimbusds/nimbus-jose-jwt/src/da13ee89febda936b234a76da3f330e39970c240/src/main/java/com/nimbusds/jose/crypto/RSADecrypter.java?at=master#cl-138

The actual random CMK generation also does take time to do, I suppose
that also has to be measured and taken into account?

Cheers,

Vladimir

--
Vladimir Dzhuvinov : www.NimbusDS.com : [email-masked]

-------- Original Message --------
Subject: Re: [jose] backwards compatibility attack on JWT impls (was:
I-D Action: draft-ietf-jose-json-web-algorithms-02.txt)
From: Brian Campbell <[email-masked]>
Date: Fri, March 15, 2013 8:03 pm
To: Juraj Somorovsky <[email-masked]>
Cc: Tibor Jager <[email-masked]>, Mike Jones
<[email-masked]>, =JeffH <[email-masked]>,
IETF JOSE WG <[email-masked]>

+1 

Thanks Juraj.

On Thu, Mar 14, 2013 at 5:52 PM, Juraj Somorovsky
<[email-masked]> wrote:
 
 Generally, such an attack could be of course *mitigated* by generating
 random CMKs, when the RSA1_5 is invalid. Thus, I would propose to
 reference Eric's
 https://tools.ietf.org/rfc/rfc3218.txt
 in your security considerations. Maybe, it would be even better to
 explicitly sketch these countermeasures as done in TLS1.2
 (http://www.ietf.org/rfc/rfc5246.txt Section 7.4.7.1.)
 
 Regards
 Juraj

_______________________________________________
jose mailing list
[email-masked]
https://www.ietf.org/mailman/listinfo/jose

---

From: "Peck, Michael A" <[email-masked]>
Date: Mon, 25 Mar 2013 15:27:17 +0000

I'm not certain of the status of the "mandatory to implement" discussion, but all of this seems like good reason for RSA1_5 to NOT be REQUIRED to implement (Table in section 4.1 of draft-ietf-jose-json-web-algorithms).  RSA1_5 is easy to implement insecurely.  There seem to be lots of caveats that have to be followed to do it "securely", and do we actually know that those will continue to be enough?

Mike

>-----Original Message-----
>From: [email-masked] [mailto:[email-masked]] On Behalf Of
>Vladimir Dzhuvinov / NimbusDS
>Sent: Monday, March 25, 2013 10:02 AM
>To: Brian Campbell; Juraj Somorovsky
>Cc: Tibor Jager; Mike Jones; IETF JOSE WG; =JeffH
>Subject: Re: [jose] backwards compatibility attack on JWT impls (was: I-D
>Action: draft-ietf-jose-json-web-algorithms-02.txt)
>
>Hi guys,
>
>https://bitbucket.org/nimbusds/nimbus-jose-
>jwt/src/da13ee89febda936b234a76da3f330e39970c240/src/main/java/com/ni
>mbusds/jose/crypto/RSADecrypter.java?at=master#cl-138
>

---

From: "Juraj Somorovsky" <[email-masked]>
Date: 25 Mar 2013 15:15:22 +0100

Hi Vladimir,

you are right, the random number generation *must not* be done in the
catch block, it could be measured and leak an information about
ciphertext validity.

I would propose this code:

if (alg.equals(JWEAlgorithm.RSA1_5)) {
	int keyLength = cmkBitLength(readOnlyJWEHeader.getEncryptionMethod());
	SecretKey randomCMK = AES.generateAESCMK(keyLength);

	try {
		cmk = RSA1_5.decryptCMK(privateKey, encryptedKey.decode(), keyLength);
	} catch (Exception e) {
		// Protect against MMA attack by generating random CMK on failure,
		// see http://www.ietf.org/mail-archive/web/jose/current/msg01832.html
		cmk = randomCMK;
	}
}

This would be perfect and also secure against timing attacks.

Regards
Juraj

---

From: Richard Barnes <[email-masked]>
Date: Mon, 25 Mar 2013 17:26:11 -0400

+1

Maybe we can't require that everyone implement the secure thing, but we can
at least NOT require that people implement the insecure thing.

--Richard

On Mon, Mar 25, 2013 at 11:27 AM, Peck, Michael A <[email-masked]> wrote:

> I'm not certain of the status of the "mandatory to implement" discussion,
> but all of this seems like good reason for RSA1_5 to NOT be REQUIRED to
> implement (Table in section 4.1 of draft-ietf-jose-json-web-algorithms).
>  RSA1_5 is easy to implement insecurely.  There seem to be lots of caveats
> that have to be followed to do it "securely", and do we actually know that
> those will continue to be enough?
>
> Mike
>
>

---

From: "Manger, James H" <[email-masked]>
Date: Tue, 26 Mar 2013 09:58:48 +1100

> 	int keyLength =
> cmkBitLength(readOnlyJWEHeader.getEncryptionMethod());

This code may be a bit more resistant to timing attacks, but it is nowhere near perfect.

Take at look at http://www.imperialviolet.org/2013/02/04/luckythirteen.html for some idea about the care required to actually resist timing attacks.

--
James Manger

---

From: "Manger, James H" <[email-masked]>
Date: Tue, 26 Mar 2013 12:30:57 +1100

> Agreed, "perfect" was a pretty strong word for that code.
> 
> I know that there could appear different processing times due to the
> decoded key length check, throwing and catching the exception, or
> randomCMK assignment. But I would say that they would consume much less
> processing time than the random number generation.
> 
> Do you have any measurements / thoughts on this?
> 
> Btw, We measured e.g. the timing differences of PKCS1 processing.
> Decryption of valid (without random number generation) and invalid
> (with random number generation) PKCS1 messages yielded a difference of
> about
> 11 microseconds.
> 
> I would be also very interested to know, if you have any major
> improvements for the code I provided.
> 
> Thanks
> Juraj

For a start the fixes need to be much lower down where the PKCS#1 padding is first handled, not way up the stack were you see an exception vs a normal return.

The Go language appears to have code with decent protections to avoid leaking crucial timing details: http://golang.org/src/pkg/crypto/rsa/pkcs1v15.go.

The Java code I found in a quick search (sun.security.rsa.RSAPadding#unpadV15) makes no effort to be constant time. I doubt there is anything (reasonable) that can be done at a higher layer (such as com.nimbusds.jose.crypto.RSA1_5) to make RSAES-PKCS1-V1_5 safe with that foundation.
[http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7-b147/sun/security/rsa/RSAPadding.java#RSAPadding.unpadV15%28byte%5B%5D%29]

Mind you, switching to RSA-OAEP might not help as the unpadOAEP(..) function in the same source file doesn't look much safer (it checks the 1st byte is 0 before doing the OAEP verification).

--
James Manger

---

From: "Juraj Somorovsky" <[email-masked]>
Date: 26 Mar 2013 01:18:24 +0100

Btw, We measured e.g. the timing differences of PKCS1 processing.
Decryption of valid (without random number generation) and invalid (with
random number generation) PKCS1 messages yielded a difference of about
11 microseconds.

Thanks
Juraj

---

From: "Juraj Somorovsky" <[email-masked]>
Date: 27 Mar 2013 08:36:45 +0100

> [http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7-b147/sun/security/rsa/RSAPadding.java#RSAPadding.unpadV15%28byte%5B%5D%29]
Such countermeasures are very precise, but are also very difficult to
implement. I do not think they are necessary to implement against the
state-of-the art timing attacks. I would say the countermeasure that I
presented is enough and would thwart practical Bleichenbacher timing
attacks.

Regards
Juraj