Why Isn't My Encryption.. Encrypting?

When I have to do symmetric encryption in .NET I always rely on ASP.NET FormsAuthentication provider do that. It is used to encrypt cookies in all ASP.NET applications (using forms authentication) so it should be strong enough. Here’s the code:

class Program
{
    static void Main(string[] args)
    {
        var encrypted = EncryptUsingMachineKey(value to encrypt);
        var decrypted = DecryptUsingMachineKey(encrypted);
        Console.WriteLine(encrypted);
        Console.WriteLine(decrypted);
    }

    public static string EncryptUsingMachineKey(string value)
    {
        var ticket = new FormsAuthenticationTicket(
            2, , DateTime.Now, DateTime.Now.AddMinutes(10), false, value);
        return FormsAuthentication.Encrypt(ticket);
    }

    public static string DecryptUsingMachineKey(string cipherText)
    {
        return FormsAuthentication.Decrypt(cipherText).UserData.ToString();
    }
}

This uses the following section in machine/web/app.config:

machineKey
validationKey=3DC93913A3E7998AE43…C519574359262
decryptionKey=9470AD8F914387CBE0…ABA8A0DB762
validation=SHA1 decryption=AES /

This means that AES is used to encrypt and HMACSHA1 to tamper proof the encrypted string.

Whats with the sudden influx on 4chan memes?

Reason for ECB – can seek.

basically everytime you made a choice you got it wrong.

-md5 should not be used anymore
-3des should not be used anymore
-ecb should not be used anymore

just leave it with the default: passwordderivebytes class and dont set any parameters you dont understand.

Of the comments so far, I think Coda Hale makes the best point. You don’t need a salt; you should be using CBC with a good, random initialization vector (which is transmitted along in plain-text). This acts like a salt in that it guarantees encrypted messages are unique even if their plain-text contents aren’t. Together with CBC it’s practically impossible to deduce information about the message contents from the encrypted data.

However, nothing so far prevents tampering with messages (which seemed to be the main concern in this post). A simple and secure solution is to add an HMAC of the plain-text data (or even the encrypted data). It would probably also suffice to insert a (cryptographic) hash code of the plain text in the plain text data somewhere, but HMAC is better established, so probably a better choice.

Note that at this point replay attacks are still possible. This may or may not be a problem depending on the application.

@Joy:
She’s called Eve because she’s the eavesdropper. If you still don’t get it (highly probable), try pronouncing the words out loud (you may have to repeat this several times).

am i the only person that thinks using NaCl for the salt is crypto-comedy-gold?
uhhh…crypto-comedy-Au?
daniel on May 18, 2009 09:31 AM

Kr-comedy-Au?

Sure ECB has its uses. You use it in whenever you don’t need encryption.
Unless you are a crypto expert, if you use it anywhere else I’m 100% sure you did it wrong and your encryption is only wasting CPU cycles but not protecting anything.
About 3DES: I disagree with those claiming it is insecure or anything, I really don’t think there is any reason to avoid it at all.
Except that it is stupid in this case, for software implementations 3DES is (a lot) slower than AES. DES (and thus 3DES) was designed with hardware implementations in mind and no regard to software. AES was designed to work well in a software implementation (but is harder to do in hardware, thus hardware often continues to prefer 3DES).
Apart from this, you absolutely need a truly random IV, not just the normal salt, and encrypted data is still trivial to manipulate (even if you can’t predict the results), so you still need a way to verify it.
A HMAC definitely is the right way to do it, but if you absolutely can’t afford it, at least (in CBC mode) add a magic last block that you verify after decoding - note that with a block size of only 64 bit that generally is in the area of brute-forceable.

I think the main point here is that you didn’t need any encryption in the first place. As a rule, you can’t trust anything you receive from the client to be in any way valid.

For me the problem is most apparent in Flash. For example, any high scores system that receives scores from a Flash-based game is hackable, and the only thing we can do is to make hacking our game a bit more difficult. Likewise, if you send any information to a Flash you have to treat it like the user saw it the moment you sent it, even if it’s not actually shown on the client.

Great post Jeff. Ignore those who happen to specialize in this area.

Well, I should amend that. Learn from them, but ignore the criticism :slight_smile:

Cue a whole slew of stupid, ill-informed questions on Stack Overflow. I pity the hapless fuckers who read the shit you post, and then use it as an authoritative source of information.

It seems to me that this entire blog is basically Jeff revealing his complete and utter lack of knowledge regarding the web, programming, or just computers in general.

What really struck me about this post was not the technical bit but the honesty that someone actually admits his mistake (undermining their reputation?)

Jeff seems to be going for a clown of software development sort of image, so this just furthers that goal.

And I marvel that Jeff still gets comments like Great post jeff. Great post? What is great about it? Aside from the incorrect terminology, that sample is such a complete FUBAR that I don’t even want to make sense of it, as it risks corrupting my brain.

I’ve been playing with encryption and found that HMAC is a great way to mix up any hashing/encryption algorithm

Haha, these cryptography trollers are just like the database administrator trollers!

@AndrÈ:
Well, I think he was being passively sexist rather than actively sexist. Whoever chose to call Eve Eve in the fist place is to blame. Why to choose that very telling name that relates to the story that is the bane of our existence? And by us I mean us women.

Programming community at large is pretty happy to sustain these stereotypes, though.

"cryptography trollers are just like the database administrator trollers!"
No cryptography trollers, they prevent people asking questron which prevents people learning how to do things correctly (or showing the traps) which then leads to weaker easy to break encription.

Why is it again that you don’t seem to support the need for basic computer science education for programmers?

Jeff never had a basic computer science education. Or, well, actually he did. He started with BASIC, and never learned C, which basically means he has a giant fscking gap in his education.

I enjoy the blog, but I don’t think he’s a CS expert - more like one of those self-taught CS people you work with in an office, and get amused by the mistakes they make because they had no formal education in computer science.

That sounded a bit harsh… but accurate enough I guess.

Right from the MS Press MCTS Exam 70-536 “Microsoft .NET Framework - Application Development Foundation, 2nd ed.” book, page 568:

“Mode - A property set to one of the CipherMode enumeration values that determines one aspect of the encryption algorithm’s behavior. This property is usually set to Cipher Block Chaining (CBC), the default. You usually should leave this set to CBC. If you do change this value, you must change it at both the encryptor and decryptor.”

And sure enough, the MSDN doco for that property says, “The default is CipherMode.CBC.”

Perhaps the REAL lesson here is don’t change default parameters in APIs unless you know what you’re doing, and why. I think that’s a common sin among many programmers (myself included, especially when I am learning a new API), to specify unnecessary parameters or override default property values just because we’re trying to figure out what the API does, and how.

I did 4 years CS at the best university in the state and we never did cryptography.

Sorry, but those saying that doing a CS degree is the answer are wrong on so many levels.