`P`

the plaintext message, `k`_{1}

and `k`_{2}

two DES keys, then the result of double DES is the ciphertext `C = DES(DES(P,k`_{1}),k_{2})

.
As everybody proficient in cryptography knows, DES is not safe due to its fixed keylength of 56 bit, which is nowadays too little to be resilent against brute force attacks.
Unfortunately, double DES does *not* alleviate this problem - it's not much safer than a hypothetical DES with 57 bit keys, which is entirely too little. The reason why it doesn't offer the equivalent of 112 bit encryption that one might naively expect is its
vulnerability to a so-called meet-in-the-middle attack.

It works like this:

- For every possible DES key
`k`

, compute_{i}`M`

and store the tuple_{i}= DES(C,k_{i})`(M`

._{i}, k_{i}) - Loop again through all possible DES keys
`k`

and compute_{j}`N`

. Check whether_{j}= DES^{-1}(C,k_{j})`N`

is the same as one of your stored_{j}`M`

. If you find a match, it's pretty likely likely that you've just found the two keys you're looking after!_{i}

Of course, step one requires a godawful amount of storage, but if you just store a hash of `M`

and recompute the full ciphertext for the (still very few) matches, it shrinks to something that might be feasible in the not-so-far future: roughly one Exabyte for a hash size of 64 bit, which should be sufficient to avoid false matches in nearly all cases.
_{i}

This is the reason why people use triple DES instead, which provides an effective key lenght of about 108 bit (not the 3*56 bit you might expect for the same reason described above).