Georg Lukas, 2013-10-14 19:06
tl;dr
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.
Preface
Some time ago, I was adding secure authentication to my APRSdroid app for Amateur Radio geolocation. While debugging its TLS handshake, I noticed that RC4-MD5 is leading the client's list of supported ciphers and thus wins the negotiation. As the task at hand was about authentication, not about secrecy, I did not care.
However, following speculations about what the NSA can decrypt, xnyhps' excellent post about XMPP clients (make sure to read the whole series) brought it into my focus again and I seriously asked myself what reasons led to it.
Status Quo Analysis
First, I fired up Wireshark, started yaxim on my Android 4.2.2 phone (CyanogenMod 10.1.3 on a Galaxy Nexus) and checked the Client Hello packet sent. Indeed, RC4-MD5 was first, followed by RC4-SHA1:
To quote from RFC 2246: "The CipherSuite list, passed from the client to the server in the client hello message, contains the combinations of cryptographic algorithms supported by the client in order of the client's preference (favorite choice first)." Thus, the server is encouraged to actually use RC4-MD5 if it is not explicitly forbidden by its configuration.
I crammed out my legacy devices and cross-checked Android 2.2.1 (CyanogenMod 6.1.0 on HTC Dream), 2.3.4 (Samsung original ROM on Galaxy SII) and 2.3.7 (CyanogenMod 7 on a Galaxy 5):
Android 2.2.1 | Android 2.3.4, 2.3.7 | Android 4.2.2, 4.3 |
---|---|---|
DHE-RSA-AES256-SHA | RC4-MD5 | RC4-MD5 |
DHE-DSS-AES256-SHA | RC4-SHA | RC4-SHA |
AES256-SHA | AES128-SHA | AES128-SHA |
EDH-RSA-DES-CBC3-SHA | DHE-RSA-AES128-SHA | AES256-SHA |
EDH-DSS-DES-CBC3-SHA | DHE-DSS-AES128-SHA | ECDH-ECDSA-RC4-SHA |
DES-CBC3-SHA | DES-CBC3-SHA | ECDH-ECDSA-AES128-SHA |
DES-CBC3-MD5 | EDH-RSA-DES-CBC3-SHA | ECDH-ECDSA-AES256-SHA |
DHE-RSA-AES128-SHA | EDH-DSS-DES-CBC3-SHA | ECDH-RSA-RC4-SHA |
DHE-DSS-AES128-SHA | DES-CBC-SHA | ECDH-RSA-AES128-SHA |
AES128-SHA | EDH-RSA-DES-CBC-SHA | ECDH-RSA-AES256-SHA |
RC2-CBC-MD5 | EDH-DSS-DES-CBC-SHA | ECDHE-ECDSA-RC4-SHA |
RC4-SHA | EXP-RC4-MD5 | ECDHE-ECDSA-AES128-SHA |
RC4-MD5 | EXP-DES-CBC-SHA | ECDHE-ECDSA-AES256-SHA |
RC4-MD5 | EXP-EDH-RSA-DES-CBC-SHA | ECDHE-RSA-RC4-SHA |
EDH-RSA-DES-CBC-SHA | EXP-EDH-DSS-DES-CBC-SHA | ECDHE-RSA-AES128-SHA |
EDH-DSS-DES-CBC-SHA | ECDHE-RSA-AES256-SHA | |
DES-CBC-SHA | DHE-RSA-AES128-SHA | |
DES-CBC-MD5 | DHE-RSA-AES256-SHA | |
EXP-EDH-RSA-DES-CBC-SHA | DHE-DSS-AES128-SHA | |
EXP-EDH-DSS-DES-CBC-SHA | DHE-DSS-AES256-SHA | |
EXP-DES-CBC-SHA | DES-CBC3-SHA | |
EXP-RC2-CBC-MD5 | ECDH-ECDSA-DES-CBC3-SHA | |
EXP-RC2-CBC-MD5 | ECDH-RSA-DES-CBC3-SHA | |
EXP-RC4-MD5 | ECDHE-ECDSA-DES-CBC3-SHA | |
EXP-RC4-MD5 | ECDHE-RSA-DES-CBC3-SHA | |
EDH-RSA-DES-CBC3-SHA | ||
EDH-DSS-DES-CBC3-SHA | ||
DES-CBC-SHA | ||
EDH-RSA-DES-CBC-SHA | ||
EDH-DSS-DES-CBC-SHA | ||
EXP-RC4-MD5 | ||
EXP-DES-CBC-SHA | ||
EXP-EDH-RSA-DES-CBC-SHA | ||
EXP-EDH-DSS-DES-CBC-SHA |
As can be seen, Android 2.2.1 came with a set of AES256-SHA1 ciphers first, followed by 3DES and AES128. Android 2.3 significantly reduced the security by removing AES256 and putting the broken RC4-MD5 on the prominent first place, followed by the not-so-much-better RC4-SHA1.
Wait... What?
Yes, Android versions before 2.3 were using AES256 > 3DES > AES128 > RC4, and starting with 2.3 it was now: RC4 > AES128 > 3DES. Also, the recently broken MD5 suddenly became the favorite MAC (Update: MD5 in TLS is OK, as it is combining two different variants).
As Android 2.3 was released in late 2010, speculations about the NSA pouring money on Android developers to sabotage all of us poor users arose immediately. I needed to do something, so I wrote a minimal test program (APK, source) and single-stepped it to find the origin of the default cipher list.
It turned out to be in Android's libcore package, NativeCrypto.getDefaultCipherSuites() which returns a hardcoded String array starting with "SSL_RSA_WITH_RC4_128_MD5".
Diving Into the Android Source
Going back on that file's change history revealed interesting things, like the addition of TLS v1.1 and v1.2 and its almost immediate removal with a suspicious commit message (taking place between Android 4.0 and 4.1, possible reasoning), added support for Elliptic Curves and AES256 in Android 3.x, and finally the addition of our hardcoded string list sometime before Android 2.3:
public static String[] getDefaultCipherSuites() {
- int ssl_ctx = SSL_CTX_new();
- String[] supportedCiphers = SSL_CTX_get_ciphers(ssl_ctx);
- SSL_CTX_free(ssl_ctx);
- return supportedCiphers;
+ return new String[] {
+ "SSL_RSA_WITH_RC4_128_MD5",
+ "SSL_RSA_WITH_RC4_128_SHA",
+ "TLS_RSA_WITH_AES_128_CBC_SHA",
...
+ "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
+ "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA"
+ };
}
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!
Cipher Order in the Java Runtime
In the Java reference implementation, the code responsible for creating the cipher list is split into two files. First, a priority-ordered set of ciphers is constructed in the CipherSuite class:
// Definition of the CipherSuites that are enabled by default.
// They are listed in preference order, most preferred first.
int p = DEFAULT_SUITES_PRIORITY * 2;
add("SSL_RSA_WITH_RC4_128_MD5", 0x0004, --p, K_RSA, B_RC4_128, N);
add("SSL_RSA_WITH_RC4_128_SHA", 0x0005, --p, K_RSA, B_RC4_128, N);
...
Then, all enabled ciphers with sufficient priority are added to the list for CipherSuiteList.getDefault(). The cipher list has not experienced relevant changes since the initial import of Java 6 into Hg, when the OpenJDK was brought to life.
Going back in time reveals that even in the 1.4.0 JDK, the first one incorporating the JSEE extension for SSL/TLS, the list was more or less the same:
Java 1.4.0 (2002) | Java 1.4.2_19, 1.5.0 (2004) | Java 1.6 (2006) |
---|---|---|
SSL_RSA_WITH_RC4_128_SHA | SSL_RSA_WITH_RC4_128_MD5 | SSL_RSA_WITH_RC4_128_MD5 |
SSL_RSA_WITH_RC4_128_MD5 | SSL_RSA_WITH_RC4_128_SHA | SSL_RSA_WITH_RC4_128_SHA |
SSL_RSA_WITH_DES_CBC_SHA | TLS_RSA_WITH_AES_128_CBC_SHA | TLS_RSA_WITH_AES_128_CBC_SHA |
SSL_RSA_WITH_3DES_EDE_CBC_SHA | TLS_DHE_RSA_WITH_AES_128_CBC_SHA | TLS_DHE_RSA_WITH_AES_128_CBC_SHA |
SSL_DHE_DSS_WITH_DES_CBC_SHA | TLS_DHE_DSS_WITH_AES_128_CBC_SHA | TLS_DHE_DSS_WITH_AES_128_CBC_SHA |
SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA | SSL_RSA_WITH_3DES_EDE_CBC_SHA | SSL_RSA_WITH_3DES_EDE_CBC_SHA |
SSL_RSA_EXPORT_WITH_RC4_40_MD5 | SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA | SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA |
SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA | SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA | SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA |
SSL_RSA_WITH_NULL_MD5 | SSL_RSA_WITH_DES_CBC_SHA | SSL_RSA_WITH_DES_CBC_SHA |
SSL_RSA_WITH_NULL_SHA | SSL_DHE_RSA_WITH_DES_CBC_SHA | SSL_DHE_RSA_WITH_DES_CBC_SHA |
SSL_DH_anon_WITH_RC4_128_MD5 | SSL_DHE_DSS_WITH_DES_CBC_SHA | SSL_DHE_DSS_WITH_DES_CBC_SHA |
SSL_DH_anon_WITH_DES_CBC_SHA | SSL_RSA_EXPORT_WITH_RC4_40_MD5 | SSL_RSA_EXPORT_WITH_RC4_40_MD5 |
SSL_DH_anon_WITH_3DES_EDE_CBC_SHA | SSL_RSA_EXPORT_WITH_DES40_CBC_SHA | SSL_RSA_EXPORT_WITH_DES40_CBC_SHA |
SSL_DH_anon_EXPORT_WITH_RC4_40_MD5 | SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA | SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA |
SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA | SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA | SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA |
TLS_EMPTY_RENEGOTIATION_INFO_SCSV |
The original list resembles the CipherSpec definition in RFC 2246 from 1999, sorted numerically with the NULL and 40-bit ciphers moved down. Somewhere between the first release and 1.4.2, DES was deprecated, TLS was added to the mix (bringing in AES) and MD5 was pushed in front of SHA1 (which makes one wonder why). After that, the only chage was the addition of TLS_EMPTY_RENEGOTIATION_INFO_SCSV, which is not a cipher but just an information token for the server.
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.
Conclusion
The cipher order on the vast majority of Android devices was defined by Sun in 2002 and taken over into the Android project in 2010 as an attempt to improve compatibility. RC4 is considered problematic since 2001 (remember WEP?), MD5 was broken in 2009.
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! (This was before BEAST made the other ciphers in TLS less secure in 2011 and RC4 gained momentum again)
All that notwithstanding, now is the time to get rid of RC4-MD5, in your applications as well as in the Android core! Call your representative on the Google board and let them know!
Appendix A: Making your app more secure
If your app is only ever making contact to your own server, feel free to choose the best cipher that fits into your CPU budget! Otherwise, it is hard to give generic advice for an app to support a wide variety of different servers without producing obscure connection errors.
Update: Server-Side Changes
The cipher priority order is defined by the client, but the server has the option to override it with its own. Server operators should read the excellent best practices document by SSLLabs.
Further resources for server admins:
Changing the client cipher list
For client developers, I am recycling the well-motivated browser cipher suite proposal written by Brian Smith at Mozilla, even though I share Bruce Schneier's scepticism on EC cryptography. The following is a subset of Brian's ciphers which are supported on Android 4.2.2, and the last three ciphers are named SSL_ instead of TLS_ (Warning: BEAST ahead!).
// put this in a place where it can be reused
static final String ENABLED_CIPHERS[] = {
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
"TLS_DHE_RSA_WITH_AES_128_CBC_SHA",
"TLS_DHE_RSA_WITH_AES_256_CBC_SHA",
"TLS_DHE_DSS_WITH_AES_128_CBC_SHA",
"TLS_ECDHE_RSA_WITH_RC4_128_SHA",
"TLS_ECDHE_ECDSA_WITH_RC4_128_SHA",
"TLS_RSA_WITH_AES_128_CBC_SHA",
"TLS_RSA_WITH_AES_256_CBC_SHA",
"SSL_RSA_WITH_3DES_EDE_CBC_SHA",
"SSL_RSA_WITH_RC4_128_SHA",
"SSL_RSA_WITH_RC4_128_MD5",
};
// get a new socket from the factory
SSLSocket s = (SSLSocket)sslcontext.getSocketFactory().createSocket(host, port);
// IMPORTANT: set the cipher list before calling getSession(),
// startHandshake() or reading/writing on the socket!
s.setEnabledCipherSuites(ENABLED_CIPHERS);
...
Use TLS v1.2!
By default, TLS version 1.0 is used, and the more recent protocol versions are disabled. Some servers used to be broken when contacted using v1.2, so this approach seemed a good conservative choice over a year ago.
At least for XMPP, an attempt to enforce TLS v1.2 is being made. You can follow with your own app easily:
// put this in a place where it can be reused
static final String ENABLED_PROTOCOLS[] = {
"TLSv1.2", "TLSv1.1", "TLSv1"
};
// put this right before setEnabledCipherSuites()!
s.setEnabledProtocols(ENABLED_PROTOCOLS);
Use NetCipher!
NetCipher is an Android library made by the Guardian Project to improve network security for mobile apps. It comes with a StrongTrustManager to do more thorough certificate checks, an independent Root CA store, and code to easily route your traffic through the Tor network using Orbot.
Use AndroidPinning!
AndroidPinning is another Android library, written by Moxie Marlinspike to allow pinning of server certificates, improving security against government-scale MitM attacks. Use this if your app is made to communicate with a specific server!
Use MemorizingTrustManager!
MemorizingTrustManager by yours truly is yet another Android library. It allows your app to ask the user if they want to trust a given self-signed/untrusted certificate, improving support for regular connections to private services. If you are writing an XMPP client or a private cloud sync app, use this!
Appendix B: Apps that do care
Android Browser
Checks of the default Android Browser revealed that at least until Android 2.3.7 the Browser was using the default cipher list of the OS, participating in the RC4 regression.
As of 4.2.2, the Browser comes with a longer, better, stronger cipher list:
ECDHE-RSA-AES256-SHA ECDHE-ECDSA-AES256-SHA SRP-DSS-AES-256-CBC-SHA SRP-RSA-AES-256-CBC-SHA DHE-RSA-AES256-SHA DHE-DSS-AES256-SHA ECDH-RSA-AES256-SHA ECDH-ECDSA-AES256-SHA AES256-SHA ECDHE-RSA-DES-CBC3-SHA ECDHE-ECDSA-DES-CBC3-SHA SRP-DSS-3DES-EDE-CBC-SHA SRP-RSA-3DES-EDE-CBC-SHA EDH-RSA-DES-CBC3-SHA EDH-DSS-DES-CBC3-SHA ECDH-RSA-DES-CBC3-SHA ECDH-ECDSA-DES-CBC3-SHA DES-CBC3-SHA ECDHE-RSA-AES128-SHA ECDHE-ECDSA-AES128-SHA SRP-DSS-AES-128-CBC-SHA SRP-RSA-AES-128-CBC-SHA DHE-RSA-AES128-SHA DHE-DSS-AES128-SHA ECDH-RSA-AES128-SHA ECDH-ECDSA-AES128-SHA AES128-SHA ECDHE-RSA-RC4-SHA ECDHE-ECDSA-RC4-SHA ECDH-RSA-RC4-SHA ECDH-ECDSA-RC4-SHA RC4-SHA RC4-MD5
Update: Surprisingly, the Android WebView class (tested on Android 4.0.4) is also using the better ciphers.
Update: Google Chrome
The Google Chrome browser (version 30.0.1599.82, 2013-10-11) serves the following list:
ECDHE-RSA-AES256-GCM-SHA384 ECDHE-ECDSA-AES256-GCM-SHA384 ECDHE-RSA-AES256-SHA ECDHE-ECDSA-AES256-SHA DHE-DSS-AES256-GCM-SHA384 DHE-RSA-AES256-GCM-SHA384 DHE-RSA-AES256-SHA256 DHE-DSS-AES256-SHA256 DHE-RSA-AES256-SHA DHE-DSS-AES256-SHA AES256-GCM-SHA384 AES256-SHA256 AES256-SHA ECDHE-RSA-DES-CBC3-SHA ECDHE-ECDSA-DES-CBC3-SHA EDH-RSA-DES-CBC3-SHA EDH-DSS-DES-CBC3-SHA DES-CBC3-SHA ECDHE-RSA-AES128-GCM-SHA256 ECDHE-ECDSA-AES128-GCM-SHA256 ECDHE-RSA-AES128-SHA256 ECDHE-ECDSA-AES128-SHA256 ECDHE-RSA-AES128-SHA ECDHE-ECDSA-AES128-SHA DHE-DSS-AES128-GCM-SHA256 DHE-RSA-AES128-GCM-SHA256 DHE-RSA-AES128-SHA256 DHE-DSS-AES128-SHA256 DHE-RSA-AES128-SHA DHE-DSS-AES128-SHA AES128-GCM-SHA256 AES128-SHA256 AES128-SHA ECDHE-RSA-RC4-SHA ECDHE-ECDSA-RC4-SHA RC4-SHA RC4-MD5
This one comes with AES256-GCM and SHA384! Good work, Google! Now please go and make these the default for the Android runtime!
Update: Firefox
Firefox Browser for Android (version 24.0 from F-Droid) comes with its own cipher suite as well. However, contrary to Chrome, it is missing the GCM ciphers to mitigate the BEAST attack.
ECDHE-ECDSA-AES256-SHA ECDHE-RSA-AES256-SHA DHE-RSA-CAMELLIA256-SHA DHE-DSS-CAMELLIA256-SHA DHE-RSA-AES256-SHA DHE-DSS-AES256-SHA ECDH-RSA-AES256-SHA ECDH-ECDSA-AES256-SHA CAMELLIA256-SHA AES256-SHA ECDHE-ECDSA-RC4-SHA ECDHE-ECDSA-AES128-SHA ECDHE-RSA-RC4-SHA ECDHE-RSA-AES128-SHA DHE-RSA-CAMELLIA128-SHA DHE-DSS-CAMELLIA128-SHA DHE-RSA-AES128-SHA DHE-DSS-AES128-SHA ECDH-RSA-RC4-SHA ECDH-RSA-AES128-SHA ECDH-ECDSA-RC4-SHA ECDH-ECDSA-AES128-SHA SEED-SHA CAMELLIA128-SHA RC4-SHA RC4-MD5 AES128-SHA ECDHE-ECDSA-DES-CBC3-SHA ECDHE-RSA-DES-CBC3-SHA EDH-RSA-DES-CBC3-SHA EDH-DSS-DES-CBC3-SHA ECDH-RSA-DES-CBC3-SHA ECDH-ECDSA-DES-CBC3-SHA FIPS-3DES-EDE-CBC-SHA DES-CBC3-SHA
My favorite pick from that list: SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA.
Enabling TLSv1.2 does not change the cipher list. BEAST is mitigated in TLSv1.2, but the Lucky13 attack might still bite you.
Send In Your App!
If you have an Android app with a significant user base that has a better cipher list, let me know and I will add it to the list.
Further Reading
- Real World Crypto 2013 by Adam Langley from Google
- Why does the web still run on RC4? by Luke Mather
- SSL/TLS in a Post-PRISM Era
- CyanogenMod issue
- Android issue #61085
- Test your browser
- A revised version of this article appeared in the Magdeburger Journal zur Sicherheitsforschung (PDF).
- Comments: HN, Slashdot, Reddit
Den Teil mit RC4_MD5 würde ich als nicht so schlimm bewerten, weil die Cipher-Auswahl auf Serverseite stattfindet, nicht auf Clientseite. Der Client verbindet sich, sagt dem Server, welche Verfahren er kennt, und der Server wählt. Nun ist die Liste der Cipher vom Client zwar nach Präferenz sortiert, aber das kann der Server ignorieren und den stärksten wählen. Daher ist es schlimmer, dass sie AES256 rausgenommen haben, als dass die erste Suite RC4+MD5 ist. Aber toll ist das natürlich auch nicht.
Jetzt stellt sich natürlich sofort die offensichtliche Frage, ob da die NSA ihre Finger im Spiel hatte. Denkbar wäre das. Der ersten Cipher auf der Liste sollte am besten etwas starkes sein, z.B. AES256, einen ordentlichen Hash verwenden, z.B. SHA256, und Perfect Forward Secrecy erlauben. Ob man jetzt außenrum RSA oder elliptische Kurven spricht, das ist im Moment im Wesentlichen eine Glaubensfrage. Leider spricht Firefox immer noch nicht TLS 1.2 (obwohl ihre Krypto-Library NSS das inzwischen partiell unterstützt), und kann immer noch nichts stärkeres als SHA-1. :-(
Comment 1:
You're implying it's "Broken".
In fact it's easier (for suitable values of easy) to attack than AES128 by a factor of 29: "In the case of AES-128, there is no known attack which is faster than the 2128 complexity of exhaustive search. However, AES-192 and AES-256 were recently shown to be breakable by attacks which require 2176 and 2119 time, respectively." [https://www.schneier.com/blog/archives/2009/07/another_new_aes.html]
There WAS a patch in cyanogenmod, reverted after a few hours!!!
http://review.cyanogenmod.org/#/c/51771/1
then reverted
http://review.cyanogenmod.org/#/c/51794/
RC4 is the recommended cipher for TLS 1.0 because it's immune to the BEAST attack.
This was definitively true before the RC4 attack uncovered in March 2013. The current state of affairs looks like countermeasures exist for BEAST (and Lucky13), but not for TLS with RC4, even though the RC4 attack is harder to perform with 220 to 230 connection attempts.
The real solution for these problems however is to implement (and enable!) TLSv1.2 support both on our servers and on our clients.
As far as I can that says that up to 2.3.7 it used the default list, and from 4.2.2 it used a better list. I don't see how both can be true.
I opened an issue report at:
Android issue #61085
But do not hold your breath. Android developers fix bugs very slowly.
You should take a look on Kenny Paterson's research regarding ciphers in SSL/TLS. The standard is broken when you use block ciphers instead of stream ciphers. There is no space for conspiracy theory in here. The android community was just reacting to this problem. Ask any cryptographer.
Clearly the author also does not understand the problem with WEP. RC4 was not broken by any means. WEP used an IV with a very small key. This combination by information theory makes the stream cipher (XOR) vulnerable to decryption and key stream collection. With enough key streams you can eliminate some non-candidate keys.
Note that it's not the variant padding between the two MD5 applications that makes HMAC-MD5 collisions harder to find than MD5 collisions (presuming the attacker doesn't already know the HMAC key). If there is a collision after the first MD5 application, in no cases will the second MD5 application somehow magically un-collide the internal state. The variant padding in the two MD5 applications serves other purposes, but doesn't help guard against collisions in cases where the attacker doesn't know the HMAC key.
Instead, the increased collision resistance comes from the fact that the first 64-byte key-dependent pad makes the MD5 internal state unknown to the attacker before any of the attacker's data hits the MD5 state.
What about going after some Internet Banking apps. I believe that Commonwealth Bank's Kaching (AU) on iOS has a dodgey SSL implementation, but haven't looked at the Android one yet.
https://play.google.com/store/apps/details?id=au.com.commbank.kaching https://play.google.com/store/apps/details?id=au.com.nab.mobile https://play.google.com/store/apps/details?id=org.westpac.bank https://play.google.com/store/apps/details?id=org.stgeorge.bank https://play.google.com/store/apps/details?id=com.bendigobank.mobile
from https://jira.cyanogenmod.org/browse/CYAN-2455
"We're not going to do anything about this for now. The proposed changes in cypher lists would leave us exposed to BEAST again."
this does not explain why cyanogenmod perferred RC4-MD5 than RC4-SHA! and why cyanogenmod still included SUPPORTED_PROTOCOL_SSLV3 as in getDefaultProtocols() & getSupportedProtocols()
So NSA still need SSLv3 downgrade attack to NULL cipher to read my secrets???!!!
Seems this change didn't get into OpenJDK. It has TLS 1.2 enabled, and AES takes the first 6 places before an RC4 cipher shows up.
(Checked in the Debian openjdk-7 sources).
Good question.
All modes of TLS rely on a "pseudo-random function" (PRF) to generate key material, nonces, etc. The PRF is based on SHA-256 by default, but the cipher suite can specify something else.
See http://tools.ietf.org/html/rfc5289#section-3.2.
For non-AEAD schemes, the hash function also controls the MAC... But GCM does not use (or require) any MAC.
Confidence in providers of crypto is shrinking... Although the argument that RC4 is needed to deal with BEAST is correct, it still doesn't address the overall situation that TLS is shipping with old and outdated algorithms.
My take is that SSL's attempt to mitigate problems in the future by supplying multiple suites (agility) has backfired, and they would be better off by removing the choice altogether.
So as a result of this post, I ended up reworking the cipher list in Play WS:
http://tersesystems.com/2014/01/13/fixing-the-most-dangerous-code-in-the-world/
In this commit, RC4_128_MD5 gets removed.
https://android.googlesource.com/platform/external/conscrypt/+/42bd279cf6a91642007955438510fda4cf99c4a0%5E%21/#F0
Google guy seems to be cleaning a lot of stuff there.