October 19, 2013

The evil of cryptographic choice -- how defaults destroy the security equation

In the light of NSA disclosures, there is somewhat of a shift towards skepticism of bad decisions. Welcome, but it is also putting light on the dark scary bad decisions that we can't deal with easily. As an example, here is a tale of woe and misfortune from Georg Lukas:

Android is using the combination of horribly broken RC4 and MD5 as the first default cipher on all SSL connections . This impacts all apps that did not care enough to change the list of enabled ciphers (i.e. almost all existing apps). This post investigates why RC4-MD5 is the default cipher, and why it replaced better ciphers which were in use prior to the Android 2.3 release in December 2010.

Georg stresses that this applies to all SSL connections ; following the herd exposes has become a bad life-style choice. For my part, I highlight that he is talking specifically about the default!

So, where did this default of evil come from? Georg dug deeper and found:

The commit message tells us: We now have a default cipher suite list that is chose to match RI behavior and priority, not based on OpenSSLs default and priorities. Translated into English: before, we just used the list from OpenSSL (which was really good), now we make our own list... with blackjack! ...and hookers! with RC4! ...and MD5!

The test suite comes with another hint:

// Note these are added in priority order as defined by RI 6 documentation.

That RI 6 for sure has nothing to do with MI 6, but stands for Reference Implementation, the Sun (now Oracle) Java SDK version 6.

So what the fine Google engineers did to reduce our security was merely to copy what was there, defined by the inventors of Java!

Whoops! It seems that the Java security team copied the list in RFC2246 from the TLS1.0 team that dates back to 1999, and it's been maintained as the Reference for up until Java 6. Android security team then copied Java security team, and hey presto ... we're secure because we're following best practices and we're unsecure because we have no clue what is going on under the hood!

Defenders of the truth will rush forth to remind us that Sun/Oracle updated their list somewhat in Java 7; granted:

Java 7 added Elliptic Curves and significantly improved the cipher list in 2011, but Android is based on JDK 6, making the effective default cipher list over 10 years old now.

But the nature of the upgrade cycle and the trap that is defaults is that those who follow the leader are screwed: Not only Android but also all of Mac OSX currently ship Java 6! Sheep! To the slaughter!

It is somewhat pointless going into the errors committed by the Java and Android teams, it's too involved, and there will be too much of an emphasis on defending, and distracting. Clearly however these errors are compounding on each other, in ways that these teams will never understand, because some of their very foundational assumptions are broken: don't copy others, don't use defaults, and don't lean on the crutch of user choice.

What is topical today is to look at the above process and highlight how easy it was to manipulate. Considering the attack by the NSA on NIST, now documented, and it is clearly seen that this attack could just as well have happened on Java's security team.

The change from the strong OpenSSL cipher list to a hardcoded one starting with weak ciphers is either a sign of horrible ignorance, security incompetence or a clever disguise for an NSA-influenced manipulation - you decide!

Conspiracy theory? That is how it was seen. But we now have the Snowden revelations, we know the modus operandi, and we now know that they did it to Dual_EC. So it gains credence.

But we also have one other data point that hints at manipulation, and that is the design of the JCE, Java's Cryptography Engine. If you are serious about security, and you reverse engineer the design (as my old Cryptix team did) then it raises serious questions. Why was it done that way? Skipping the long discussion, we can summarize with the one thing that JCE screams out at the reviewer:


The entire Java Cryptography approach (Architecture is an odd term here?) was designed to take control of the crypto. Not only the crypto, but the entire market for Java Crypto. Without a clear mandate to control the market, there is no good engineering reason to do it that way, and dozens of engineering reasons to run screaming.

Of course, the design is no smoking gun. And people involved will deny it as conspiracy theorizing, and damn the detractors to high hell.

But things have changed. We are now in the world where all major players have to prove the negative: since the disclosure that Apple, Google, Facebook, Microsoft and probably the others are delivering real time data to the NSA, we can conclude that the JCE attack was a likely one, and the onus is now on the Java security team to deal with this new reality.

That's a negative that will be difficult to prove. Which pretty much undermines the entire foundation of Oracle/Sun's approach to crypto. All of Java crypto is now completely undermined by the new revelations.

What to do? If one is stuck in Java-lala-land, as many of us are? Only because some will dismiss any thought process without a list of positive suggestions, here are some options:

  • Use BouncyCastle (my old Cryptix team no longer being active). But, you have to use their non-JCE lightweight library. Which means you have to get adept at cryptoplumbing.
  • Use Niel Alexander's port of NaCl to Java. This appears to be a clean port, although lacks any semblance of documentation. And, using NaCl only covers basic needs -- the cryptobox idea assumes you want to send an authenticated message from one place to another, with PK. It doesn't cover you outside that box, so to speak.
  • It's your job, do it! This means becoming an adept at crypto. The upside of this is you get to align your responsibilities. The downside is that you have to learn quickly, and get good at asking for help from others. FTR, this is what I do.

What is clear is that we can no longer use the recommended crypto from Java, and at the same time maintain that we've done our job as security folk if our threat model is serious. Using Java's JCE is only workable if you are the threat model, or are otherwise an adept at cognitive dissonance.

Posted by iang at October 19, 2013 01:55 PM | TrackBack

... The guilty party, he asserts, isn't the Android development team, but Java developers – and in a demonstration of how long a zombie decision can keep shambling around calling “braaains!”, it's an implementation recommendation first made in 2002. ...

Posted by: El Reg - Zombie Encryption... at October 28, 2013 11:01 PM
Post a comment

Remember personal info?

Hit preview to see your comment as it would be displayed.