**A block cypher with ECB for symmetric encryption**

*(Applies to AES, 3DES, ... )*

Here is a [post][1] regarding how ECB mode results in code that isn't encrypted.  

**The wrong way**

    public static string Encrypt(string toEncrypt, string key, bool useHashing)
    {

    byte[] keyArray = UTF8Encoding.UTF8.GetBytes(key);
    byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt);

    if (useHashing)
        keyArray = new MD5CryptoServiceProvider().ComputeHash(keyArray);

    var tdes = new TripleDESCryptoServiceProvider() 
        { Key = keyArray, Mode = CipherMode.ECB, Padding = PaddingMode.PKCS7 };

    ICryptoTransform cTransform = tdes.CreateEncryptor();
    byte[] resultArray = cTransform.TransformFinalBlock(
        toEncryptArray, 0, toEncryptArray.Length);

    return Convert.ToBase64String(resultArray, 0, resultArray.Length);
    }

The error is in the following line

 { Key = keyArray, **Mode = CipherMode.ECB**, Padding = PaddingMode.PKCS7 };

-----

Disclaimer
-----------
The following recommendations is only an aggregation of comments on the blog that seem relevant and logical.  I'm not a crypto expert and hope someone more knowledgeable than I am will vet these answers for completeness and accuracy.

-----

Some highlights from the blog's comments

 * It derives both the key and the IV from a passphrase using SHA-384, destroying the purpose of using a chaining mode with an IV.
 * Triple DES is slower than AES shouldn't be used for new code. AES is preferred. MITM is the only known attack vector for 3DES
 * In .NET MD5CryptoServiceProvider and TripleDESCryptoServiceProvider should be disposed
 * Use SHA-256 instead of MD5; not because unsuitable for message digests and signatures, but because the digest length is 128 bits; far shorter than 3DES's key size of 168 bits
 * If you are considering ECB for whole disk encryption, consider CTR instead
 * One reason in support of ECB (versus CBC) is the ability to seek in the stream. CBC makes each forward block dependent on previous blocks.
 * One reason against ECB is because it is vulnerable to replay attacks
 * Nothing so far prevents tampering with messages A simple and secure solution is to add an HMAC of the plain-text data 
 * Commentor Reimar mentions that a block size of 64 bits is in the area of being brute forceable

**The right way**

Quoted from commenter Coda Hale

1. Generate a random IV of a length equal to the encryption algorithm's block size (for 3DES, that's 64 bits).

2. Run the user's password through a hash algorithm with a digest size equal to or greater than the key size of the encryption algorithm. SHA-256 is a fine choice; just drop the unused bits off the end. Your aim here is simply to diffuse the entropy in the user's password across the entire key (otherwise big chunks of the key are predictable).

3. Initialize the encryptor with the key and the initialization vector.

4. Encrypt your data.

5. Prepend the initialization vector to the encrypted data.

That said, the only kind of people who should be writing code like that are people who understand *why* they should be writing code like that. I'm not seeing that here, so a better description of what your algorithm should look like is:

1. Pick a reputable cryptographic library, like Bouncy Castle.

2. Pick a high-level abstraction from the library which matches what you want to do (e.g., send a confidential message).

3. Do what it says.




  [1]: http://www.codinghorror.com/blog/2009/05/why-isnt-my-encryption-encrypting.html