On 21 July 2013 22:40, Ben Lincoln <f70c9...@beneaththewaves.net> wrote:
> Maybe I am misunderstanding (and I apologize if so), but I don't think > authenticated encryption will address the main problem I'm trying to solve. > Preventing tampering is important (and I think some of what I suggested has > the effect of making it at least a little harder to tamper with the data), > but it's by far the secondary concern. > Unless your software is horribly broken to begin with - and it arguably is given what you're attempting to do - then a MAC or authenticated encryption is sufficient to solve *most* of your problem. > > The main problem is trying to reduce the likelihood that the system will > decrypt data of a different type than it expects, and then display that > decrypted data to the user (IE allowing them to decrypt arbitrary data > without themselves knowing the encryption key). Unless I'm missing > something (and that is certainly possible), then the data will always pass > an authentication check, because it's always generated by the system in > question - it just isn't intended to be decrypted and displayed by that > specific part of the application. > The MAC covers the entire data blob, so assuming each attribute you wish to store/retrieve has context information associated with it then it is impossible for the attacker to forge. Say, you have a data block which contains, someSensitiveVariable=topsecretinfo then trying to send that to a display function that expects someVariableToBeDisplayed=info won't work because your code checks the variable name (a trite example but you get the idea). If the attacker determines field boundaries within the data blob, they still cannot forge a sensitive attribute into an unsensitive one because they cannot calculate the required MAC because they do not have the required secret key to do so. If it were I implementing a scheme such as this, I'd do the MAC after the encryption, include a nonce value in the blob as well as an expiry timestamp and an identifier for the user; I'd also use a different secret key for the MAC as to the encryption. Be very careful with your padding and field delineation. And as CodesInChaos said above, use a different cryptographically random IV for encrypting each different data blob and for the MAC. The first reason I said "most of your problem" above is that an attacker can resubmit a valid blob and have it processed identically, viz. a replay attack. For example, someSensitiveTransactionAmountToTransfer=10000 could be resubmitted and your software cannot tell whether it's a duplicate or not. The only way past that, as far as I can see, is to keep track of the nonce values in which case you're back to square one because you need to have a central transaction store and may-as-well just put all your sensitive info in there anyway, which I strongly suggest you should be doing in the first place. The second reason I said "most of your problem" is slightly more subtle. If an attacker can create encrypted fields from *plaintext* data, say they enter their information in a form which is then encrypted and stored in the browser, then the attacker can use the application as an oracle. If we furthermore consider the sensitive data and non-sensitive data in the vein of error-correcting codes and that these span a space much smaller than the possible space over F_2^n, and we also assume the block-size of the cipher is small enough (64-bits is enough), it may be possible for the attacker to iterate over that search space and generate the corresponding ciphertext blocks, storing them in a table. By comparing the cipher-text of sensitive data blobs to the table, the attacker can then identify the corresponding plaintext, essentially decrypting the sensitive data without requiring the key. There are optimisations to this attack which I haven't described here. This last problem can be solved by using temporal or derived secret keys, i.e. you have the master secret key and for each data block you combine that with some cryptographically random data to derive a "one-time" secret key. However, as you'll notice we're already getting quite messy and the scope for making a complete hash of things (pun intended) has dramatically increased. > > Using separate keys for separate types of data will go a long way there, > but I am trying to come up with a completely separate mechanism that > operates using a different method, but which will also help prevent the > unwanted outcome even if someone makes a mistake and uses the same key for > sensitive and non-sensitive data. In other words, the mechanism I'm trying > to come up with can't involve using different keys, because I already have > a mechanism based on that principle. > For comparison, think of physical safety features in industrial equipment. > The B Reactor at Hanford had a gravity-based system that would > automatically insert the control rods in the event of a power failure, but > there was also a system that could drop a bunch of neutron-moderating fluid > and/or ball bearings into the reactor in case the first system jammed or > was inoperable for other reasons. Because they were based on different > designs, it's unlikely that they would both fail in an emergency, unless > the emergency involved loss of gravity locally. > Cryptography is not nuclear reactor design, although there is a pertinent similarity in that in both cases if you're not confident in what you're doing then it's best to copy *precisely* a tried-and-tested solution. While there is a minimum complexity, keeping it as simple and easy to analyse as possible is a very good idea: the more convoluted your design is, the more likely it is to screw-up. > > Alternately, in software development, we strongly encourage developers to > check their code for e.g. buffer overflow vulnerabilities, but we also > strongly encourage them to perform input validation so that e.g. if they > are working on one piece of code and someone less-capable is working on > another, and that second person introduces a buffer overflow issue, > malicious input never makes it to the second system because the input > validation of the first system catches it (or passes the first mechanism > but is stopped by the second, if the skill of the two developers is > reversed). > > Using HMAC or AES-GCM would improve the overall security of the system, > but I don't think either of them address the core issue I have. That core > issue seems like it's outside the scope of the encryption, but the reason > I'm asking here is because I don't want to compromise the encryption in > some way as a result. It does *almost* solve your issue, with the caveats above. Peter > > > On 2013-07-21 13:55, CodesInChaos wrote: > >> 1) If you want to prevent tampering, use a MAC, not a cipher. My >> recommendation is HMAC-SHA-2. Be sure to use a constant time equality >> check while verifying the MAC. >> 2) If you want to encrypt something symmetrically, use authenticated >> encryption. Either with a specialized mode, like AES-GCM or with an >> encrypt-then-mac scheme. Use a proper IV and don't forget to include it >> in the MAC. >> 3) Use separate keys for different uses. This avoids interactions >> between different parts of the software. >> If you want only a single key in the config, then don't use it >> directly. Instead derive a distinct key for each usage with a key >> derivation function. >> My recommendation for a KDF is HKDF with HMAC-SHA-2 as building >> block. >> >> _______________________________________________ > cryptography mailing list > cryptography@randombit.net > http://lists.randombit.net/mailman/listinfo/cryptography >
_______________________________________________ cryptography mailing list cryptography@randombit.net http://lists.randombit.net/mailman/listinfo/cryptography