2
$\begingroup$

I found the below code online, but in its original state, the encryption was not using any padding (Padding.None), and was encrypting in blocks of 8. I wasn't able to get this code to properly encrypt / decrypt data so I was forced to have it encrypt the full length of the text. Is there something fundamentally wrong with what I have done? If so, could someone please show me the proper way to encrypt text in blocks of 8?

// 168-bit (three-key) 3DES (Triple-DES) encrypt a single 8-byte block (ECB mode)
// plain-text should be 8-bytes, key should be 24 bytes.
public byte[] TripleDesEncryptOneBlock(byte[] plainText, byte[] key)
{
    // Create a new 3DES key.
    TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider();
    // Set the KeySize = 192 for 168-bit DES encryption.
    // The msb of each byte is a parity bit, so the key length is actually 168 bits.
    des.KeySize = 192;
    des.Key = key;
    des.Mode = CipherMode.ECB;
    des.Padding = PaddingMode.None;
    ICryptoTransform ic = des.CreateEncryptor();
    byte[] enc = ic.TransformFinalBlock(plainText, 0, 8);
    return enc;
}
public byte[] TripleDesDecryptBlock(byte[] plainText, byte[] key)
{
    // Create a new 3DES key.
    TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider();
    // Set the KeySize = 192 for 168-bit DES encryption.
    // The msb of each byte is a parity bit, so the key length is actually 168 bits.
    des.KeySize = 192;
    des.Key = key;
    des.Mode = CipherMode.ECB;
    des.Padding = PaddingMode.None;
    ICryptoTransform ic = des.CreateDecryptor();
    byte[] dec = ic.TransformFinalBlock(plainText, 0, 8);
    return dec;
}
// Encrypt Text
textBox5.Text = ByteToString(TripleDesEncryptOneBlock(StringToByte(textBox5.Text),  
    StringToByte("1 2 3 4 5 6 7 8 9 1 1 2 ")));
// Decrypt Text
textBox5.Text = ByteToString(TripleDesDecryptBlock(StringToByte(textBox5.Text),  
    StringToByte("1 2 3 4 5 6 7 8 9 1 1 2 ")));

My Related question on stack overflow

$\endgroup$
2
  • 1
    $\begingroup$ I think this question is hard at the limit between Stack Overflow and Cryptography stack exchange ... I'm not sure on which side of the limit. (Thomas' answer is clearly on "our" side of the limit.) $\endgroup$ Commented Aug 9, 2011 at 14:28
  • $\begingroup$ Hi @Evan, welcome to Crypto.SE! FYI, probably only a fraction of cryptographers here are skilled at reading C# code and understanding what cryptographic operations the code wil do. So, in the future, if you are able to translate this into a specification of what the code is doing (e.g., in mathematical notation), it is possible that this might facilitate a broader range of responses. Either way, thanks for participating! $\endgroup$
    – D.W.
    Commented Aug 11, 2011 at 2:26

1 Answer 1

5
$\begingroup$

3DES is a block cipher which processes "blocks" of 64 bits. A block cipher is not sufficient to encrypt a message, defined as a sequence of potentially many bytes. Hence the use of a mode of operation which organizes things; this may imply some padding, and an Initialization Vector.

TripleDESCryptoServiceProvider can do all that: you specify the key, the chaining mode, the padding and the IV, and then you call CreateEncryptor() (or CreateDecryptor()) which returns an ICryptoTransform instance, on which you call TransformBlock() and TransformFinalBlock() to process all your data. You can process the data by chunks (you call TransformBlock() several times, and finally TransformFinalBlock() once).

The code you show is trying to do the opposite of what you seek: it uses TripleDESCryptoServiceProvider to process a single block, without any chaining or padding (hence the use of ECB and no padding).

Note that:

  • ECB is known to be a weak chaining mode (it leaks quite a lot of information on typical input data).
  • Secure modes of operation (e.g. CBC) need an appropriate IV: in the case of CBC, it must be chosen randomly and uniformly with a cryptographically strong random generator, and it must never be reused (the point of the IV is that you can reuse the same key for several messages, as long as each message has its own IV). The IV is normally transmitted along with the encrypted message (in the clear), since the decryptor will need it.
  • Ciphers process bytes. A "string" is a sequence of characters, thus a conversion step is needed. I assume that your StringToByte() method (which you do not show) does that. Beware of charsets: you want the conversion to always operate the same way, regardless of how the local machine was configured.
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.