On Tue, Apr 3, 2012 at 9:35 AM, ianG <i...@iang.org> wrote: > Belated reply!
On belated reply deserves another. Actually Uncle Sam has me busy doing taxes and GSoC busy with mentoring activities. > On 21/02/12 06:40 AM, Kevin W. Wall wrote: >> >> First of all, let me thank all who have responded for lending >> your expertise. I am just picking out Ian's to respond to >> because of his suggesting dividing up the IV into >> >> random||counter||time >> >> but I do appreciate everyone else's comments as well. >> >> On Mon, Feb 20, 2012 at 7:11 AM, ianG<i...@iang.org> wrote: >>> >>> On 20/02/12 18:11 PM, Kevin W. Wall wrote: >>>> >>>> >>>> Hi list, >>>> >>>> This should be a pretty simple question for this list, so please pardon >>>> my ignorance. But better to ask than to continue in ignorance. :-) >>>> >>>> NIST refers to "combined" cipher modes as those supporting *both* >>>> authenticity and confidentiality, such as GCM and CCM. >>> >>> >>> My personal impression of such things is that although they can give a >>> paper >>> sense of authenticity, it is not good enough to rely on at an application >>> level because of software layering issues. In the past, I've preferred >>> to >>> use a heavyweight signed plaintext packet, then encrypted with a >>> light-level >>> HMAC or similar. So, yes it is authenticated twice, but they are at >>> different strengths / semantics / layers. >> >> >> Yes, well, that is all well and good for some things, but when the primary >> use of encryption nowadays is to encrypt short strings like credit card >> numbers and bank account numbers, most developers are not going to >> put up with the additional space& CPU overhead of both a dsig and an >> >> HMAC. Based on your recommendation from several years ago, we had >> originally >> used an HMAC-SHA1, but changed it to an HMAC-SHA256 after recommendations >> from the initial NSA review. However, we (OWASP ESAPI) only do this for >> when the user decides to use an unauthenticated cipher mode. > > > > Those statements are ... interesting. When protecting bank account numbers, > credit card numbers, etc, you really don't care that much. Most all of them > are available for a price on your local phishing market, and they aren't > transactions. You're protected other ways. Which is to say, you don't need > bullet proof protection, you can afford to be efficient. The software won't > be bullet proof ... Phish markets aside, most developers encrypt bank account #s and credit card info because of compliance issues like NACHA and PCI DSS. And truth be told, about the only threat that this addresses is one of a rough DBA heisting your DB of CC information or bank account #s. If your code has SQLi vulnerabilities, an adversary is still going to walk away with your database. > Secondly, think of your architecture. Anyone who is protecting CCs with > this model will likely not be able to show that the authentication is in > good nick. So if there is a problem, you are left with the statement "our > security is good" which sits oddly with the statement "somebody lost their > money." The big risk in having CCs or banking info stolen is the subsequent (usually class action) lawsuits that usually follow. So these things are done as part of following industry "best practice", in which case you can at least claim that you've done due diligence and if you lose, at least the claimants in the lawsuit are awarded treble damages. So the your "our security is good" approach is mostly done to satisfy this due diligence and to a lesser extent to show the PCI and NACHA auditors that you done what you were asked to do so that you don't end up having to pay fines. It's classic CYA security. > This is why I use digsigs over the money packets - the digsig > carries with the money instruction; the HMACs are thrown away as ephemeral. > Layering is important for security too... Dsigs are harder from an operational perspective as well as harder to teach developers. Plus it can be a significant performance hit. But I agree, both have their place. > In that sense, lower layer HMAC-SHA1 is overkill. IMHO, and, in my future > design I intend to reduce that a lot. The overkill seems to be mostly in the overhead of storing it along with the IV+ciphertext. The overhead is significant when encrypting short strings such as CC#s, SSNs, etc. Generally these issues come up when trying to make legacy code PCI or NACHA compliant. The DB already exists and table space is already allocated so storage space is at a premium. Usually, I recommend that development teams use something like Oracle's Transparent Data Encryption and Oracle Wallet. But our DBAs are reluctant to allow developers to use it; say it's too much of a performance impact on the DB engine. I say take the development savings and put it into some new upgraded hardware. I generally loose those arguments. :-( > To tip my hand here somewhat I'm thinking of GCM. > > (Digression.) Now, this thread was useful to me because I started reading > up on new modes and so forth, and combined that with my past experiences. > What I wanted was a fast AES mode coupled with a heavyweight keyed CRC for > opportunistic/DOS protection. > > Hey presto - GCM is that! (I think, haven't finished reading yet.) If you > look at the formula for Galois, it is basically a CRC expanded out to 128 > bits. Perfect! Fast! > > But notice I sat heavyweight keyed CRC. I consider a Hash MAC to be > overkill - SHA1 is way too much trouble for this. > > So your statement above is ... curious. On the one hand, the NSA apparently > advised you to turn the overkill of HMAC-SHA1 into the blended horse > milkshake of HMAC-SHA256 ... which you do, unless you're using GCM! Or > CCM... > > I remain bemused and can't wait to hear what the NSA says in the next review > :) Me too. I have some rather pointed questions to ask them about some other things the supposedly reviewed and are weaknesses that I think (given their reputation) they should have caught. They didn't mention it. I'm not sure if that was intentional or they just had junior people looking at ESAPI or if they had too many other higher priorities and are overworked like most of us so didn't get sufficient time to study it or what. (I'm hoping it's the latter, but not so sure.) > > >>>> So my first question: Are there ANY "combined" cipher modes >>>> for block ciphers that do not cause the ciphers to act as a key >>>> stream? (That seems to be cause most of the ones I found build >>>> the confidentiality piece around CTR mode.) If "yes", please name >>>> a few (especially those with no patent restrictions). >>>> >>>> I know when you have a cipher that acts in a streaming mode, >>>> that you need to be careful to use a unique IV for every encryption >>>> performed with the same key. >>> >>> >>> >>> Well. With basic modes like CBC, if there is no variation in the early >>> parts of the packet, those blocks will encrypt the same. >>> >>> A good plaintext packet design can push strong variation into the first >>> bytes. e.g., the MAC can go at the beginning not the end. It used to be >>> customary to put the MAC at the end because hardware calculated it and >>> streamed it at the same time, but software doesn't work that way. >>> >>> (There was a paper suggesting that encrypt-then-mac was better than >>> mac-then-encrypt, but I vaguely recall this result only applies under >>> some >>> circumstances. Does anyone recall how important this issue was?) >> >> >> I've read a few papers and blogs on this topic. The one that sticks in >> my mind was one of Nate Lawson's blogs. I just looked it up and I >> think it was: >> >> http://rdist.root.org/2010/09/10/another-reason-to-mac-ciphertext-not-plaintext/ > > > > Um. There are a lot of assumptions in that post. Firstly, that someone is > sending you garbage packets and you can get a benefit by dropping them at > the MAC phase not the decrypt. Think about it ... And that could be the case, depending on how people use ESAPI. Duong and Rizzo mentioned that early versions of ESAPI 2.0 were vulnerable to padding oracle attacks. (That was caused by sloppiness on my part. Besides a subtle side-channel timing attack that could be used as an oracle, I also stupidly had the exception message in two different spots with slightly different error messages. Duh!) > Surface area - ditto. If you are subject to that, you have other problems. Well, the thing is, you just don't know. We are not developing an application here--where we would have a fairly good idea of the context and thus could develop an appropriate threat model. Rather we are developing a class library full of common security controls. It's very hard to tell how developers using your class library are going to expose your API so you more or less plan for the worst case scenario. Thus the choice to MAC the IV+ciphertext. But my first recommendation is to use an authenticated mode such as GCM or CCM. Unfortunately, the off-the-shelf Oracle SunJCE, which is the default, reference implementation of the Java Cryptography Extensions does not support ANY authenticated cipher mode. If you want this, you need to use something like Bouncy Castle or an alternate JCE provider. Unfortunately, in many commercial IT shops, trying to get permission to use Bouncy Castle is a hard sell. It was in my organization; I had to jump through all kind of hoops to first get it on our "approved product list" before finally getting approval to use it. It took about 3 or 4 weeks. And buying a commercial crypto JCE library is usually even more work. So most developers just give up and settle for using SunJCE and one of the cipher modes that it supports. > Finally - subject to side-channel attacks. If you are, then we are in > another ballgame. I don't think you are. Having multiple "stacked applications" on a single physical host is common. Unfortunately, applications are generally not assigned hosts based on any security requirements; rather they are "stacked" to maximize the CPU utilization and place as many applications on a server as possible. So one possible threat model is being attacked by a hostile application (developed by a rogue developer) that is running on the same physical server as your application. So getting detailed timing information is not that difficult. Plus, once you know about certain timing side channel attacks it is not that difficult to address them. Becoming aware of them is the hard part. (Note: I only addressed _timing_ side channels, not any other type. And also, only the ones I was aware of. Duong and Rizzo's research on padding oracles convinced me that this was worth doing. You do what you can and what you know about. It didn't add very much complexity to fix.) >> Based on this and some additional comments from Duong& Rizzo, we decided >> to >> >> use the encrypt-then-MAC approach to ensure the integrity of the >> ciphertext. >> (Keep in mind this was designed around the time that Duong and Rizzo >> automated a padding oracle attack with their POET software.) >> >> However, we skipped the MAC calculation if the cipher mode chosen >> was an authenticated mode like CCM or GCM. The assumption (hopefully >> a correct one), was that an authenticated cipher mode was sufficient. > > > > That bit! To repeat my earlier words - this is why I went for a lightweight > MAC approach. It fits 99% of needs. And the remaining needs won't be > properly served either, because architecture will likely interfere. Not sure what you mean by the "architecture will likely interfere". Could you explain please? >> In ESAPI (ignoring all error / exception handling, etc.), using such >> a "combined" mode, distills down essentially to something like this >> for the encryption: >> >> // This is in essence what ESAPI does for combined cipher modes like CCM& >> GCM >> >> // Assume a 128-bit AES key for this example. >> public class Encryptor { >> private static SecureRandoma prng = new SecureRandom(); >> ... >> public byte[] encrypt(SecretKey sk, byte[] plain) throws Exception { >> ... >> Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding"); >> byte[] ivBytes = new byte[ 128 / 8 ]; // 16 bytes (AES block >> size) >> prng.nextBytes(ivBytes); >> IvParameterSpec ivSpec = new IvParameterSpec(ivBytes); >> cipher.init(Cipher.ENCRYPT_MODE, sk, ivSpec); >> return cipher.doFinal( plain ); >> } >> ... >> } >> /////////////////////////// >> >> However, as you can plainly see, there is no attempt here to prevent >> the reuse of an IV for a given key. The assumption was originally, >> that the random IV use was sufficient, but after reading recent comments >> on entropy pools at boot-up time (when application servers typically >> are started from /etc/init.d scripts), I'm not so sure. > > > > Yes, exactly. When Zooko and I designed the random||counter||time construct > it is because we knew that some or many servers could get into a > pathological mode w.r.t. entropy. And saying "have good entropy" is like > telling teenaged girls not to hang around teenaged boys. I'm definitely going to replace the prng.nextBytes(ivBytes); with what you and Zooko used...the random||counter||time construct. That's now on my list for 2.1. Fixing this will allow the use of streaming cipher modes too. (For now, I make it difficult--although not impossible--to use such modes.) > >> However, above more or less is considered best practice to using Java for >> symmetric encryption when you are using an authenticated mode. >> >> The question is whether or not this is sufficient. I suppose like >> most everything in information security, it depends on one's threat >> model. > > > > (Business model.) You are protecting account numbers. It's probably OK. > Nobody has ever cracked encryption to steal account numbers - coz the > winnings just ain't worth a packet level attack. The threat it is meant to prevent is a DBA walking away with 20M bank accounts or credit card #s. Hey, it happed at my credit union (although with significantly lower #s, about 8-10 yrs ago--definitely it was pre-PCI / pre-NACHA). > Also, the servers that suffer pathalogical entropy problems are typically > embedded devices like routers, not business servers such as you are > postulating. > > That said, what we proposed isn't any more expensive than collecting some > stuff from the OS's /dev/random. Ooh...did that in a custom EntropyPool class we did in a proprietary API. Had 'high', 'medium', and 'low' settings. Default was 'medium' which read from /dev/urandom (non-blocking). 'High' read from '/dev/random' (blocking) and low just used SecureRandom. The Javadoc clearly documented the blocking behavior of setting the entropy pool security to 'high', but the developer never read it. Put it out into production. Worked great for awhile until one week when they had usually high traffic, they started getting timeouts which they traced to the blocking behavior. Glad I wasn't holding the pager that day! 8-) > >> Unfortunately, when trying to provide a generally reusable >> (and simple) security API that does not require ordinary developers >> to be experts in applied cryptography, one cannot go over-the-top. >> If the crypto is too hard to use, has too much CPU overhead, or >> makes the resulting cipher text excessively long, developers simply >> will not use it. The will instead just use ECB mode and not worry >> about things like cryptographic attacks that they don't know anything >> about and couldn't be bothered with anyhow, even if they did. >> >> So our goal is to ensure that the crypto is strong enough to protect >> things like credit card #s, bank account info, passwords (where >> cleartext passwords are needed for things like DB connections), >> and producing cryptographic tokens. We are not concerned about >> protecting nuclear lauch codes. Besides, it is more than likely >> if the crypto is the weakest link (and it rarely is; usually >> XSS and SQLi vulnerabilities abound), the weak part of the crypto >> will be in the way that the dev teams manage their encryption keys. > > > > Yeah. But you can eliminate weak spots like "have good entropy" without > introducing any other costs :) Well 'good' is a relative term. How 'good' is reading from /dev/urandom? Probably pretty good. But what about when you are starting up 30 or 40 WebLogic Server or Tomcat applications right after boot-up? Still 'good'? Maybe, maybe not. There's been a lot of debate about that on this list. Only thing I can say is given the high price you pay for servers, it sure is surprising that they all don't come with a standard hardware-based CRNG. >>>> So my second question is, if all the "combined" cipher modes all >>>> cause a cipher to act as if it is in a streaming mode, is it okay >>>> to just choose a completely RANDOM IV for each encryption? >>>> Because it sure doesn't seem to be feasible to record all the IVs >>>> for a given key to make sure that an IV isn't reused. If that is not >>>> acceptable, then how does one ever address this? >>> >>> >>> >>> Random is good. Also, using a counter that always goes up is good. >>> Another >>> possibility is to use a sufficiently fine timesource. >>> >>> All of these devices look good on paper but have some edge cases. One >>> way >>> is to cram them all into the IV as one lump: >>> >>> random||counter||time >> >> >> So, are you advising that rather than requesting 16 bytes of >> randomness and turning that into an IvParameterSpec, I should request >> something less and then combine it w/ a counter and time? > > > > Yes. Our thesis is that your downstream developers are as much your threat > as anyone else :) > Or developers in general! ;-) >> In Java, >> time is a long (4 bytes)? So how much for the 'random' piece and >> how much to allocate for the 'counter' portion? > > > > 4 bytes time, 4 bytes counter, 8 bytes random? > > When I wrote all this into SDP1 I did it differently, but the details were > more exotic. > > > >> And if a dev team were to use 3DES, we only have an IV of 8 bytes? >> How should that be divided up? > > > > I would take the above 16 bytes of random||counter||time, run it through > SHA3 10,000 times, then take the first 8 bytes of the result. Explain to > them that this is an NSA recommendation for improving the strength of TDES, > but really the NSA recommends AES... > Yeah...doing that ought to make it run slow enough that they will switch from TDES to AES for sure. ;-) > >> Also, if we are doing this, is it important to remember the 'counter' >> across Java VM restarts or can we just reset it to 0 at that point? > > > > Exactly - that is why the time is there. You can't reliably remember the > counter across restarts - it is impossible for the crypto designer to > predict how the counter is stored; so we have to assume that it could be > ephemeral. Indeed, we probably want it to be - imagine the complications of > insisting that the IV fields be stored in a SQL database, and what that does > to security :P So the time is in there for the moments when we are talking > about fast restarts, and counter := 0. > > If the mobo clock's battery is flat, the counter is being reset by some mad > power glitch, and entropy is a half filled glass, then you can at least say > you did the best you could. > > > >>> With most algorithms these days, you've got 16 bytes in the first block. >> >> >> Major exception being w/ 3DES, which some developers still use for >> legacy reasons. You have no idea! Sure is easier to create shitty software than it is to get rid of it though. > > If you are designing a mode and protocol, it is unclear to me why they are > insisting on using 3DES with it. > It usually is one of two lines of reasoning. One is that we have a vendor product that uses 3DES and we have not control and we've been too cheap to by maintenance for the software since 1999 or so. The other line I've given is that "this application is strictly in a maintenance-only mode; we have no developers to change it. We don't even know where the software is". Not sure how common this is in the finance industry, but it is very common in telecommunications sector. Anyhow, thanks for all the suggestions. Definitely going to use them in ESAPI 2.1, which I'll start working on as soon as GSoC is finished in late summer. Thanks again, -kevin -- Blog: http://off-the-wall-security.blogspot.com/ "The most likely way for the world to be destroyed, most experts agree, is by accident. That's where we come in; we're computer professionals. We *cause* accidents." -- Nathaniel Borenstein _______________________________________________ cryptography mailing list cryptography@randombit.net http://lists.randombit.net/mailman/listinfo/cryptography