0

I'm writing an application in C# that needs to decrypt some data that was encrypted by some legacy software. The legacy code loops over the unencrypted bytes in chunks of 8 and encrypts them via TripleDES in CBC mode. It then handles the remaining bytes by using TripleDES CFB, using a block size of the remaining amount (in this specific case, 2).

I can unencrypt the data from the first phase fine in C# using System.Security.Cryptography.TripleDES, since it allows for block sizes of 64 bits (8 bytes). The TripleDES class won't allow for a block size of 16 bits, however. The following code throws an error that says "Specified block size is not valid for this algorithm":

TripleDES provider = TripleDESCryptoServiceProvider.Create();
provider.Mode = CipherMode.CFB;
provider.BlockSize = 16; // exception thrown here

I'm assuming this is in place due to the weak nature of small block sizes. Unfortunately, it's what I'm stuck with. Are there any free third-party libraries that might support a 16-bit block size for TripleDES/CFB? Or are there any tricks I can use on this data set to make this work? I've checked the DES class to see if it supports 16-bit block sizes, but no dice...

I'm no cryptography expert, so if I end up having to roll my own code for TripleDES (over 2 bytes...grrr), any straight-forward articles on the details of the algorithm would be super helpful.

iddqd
  • 105
  • 1
  • 10
  • There are no block ciphers with block size 2. You've got something wrong there. – usr Jun 28 '12 at 14:17
  • @usr It's entirely possible. The legacy code is using a third-party library that won't work in C#. For the "remainder portion" of the algorithm, it's telling this library to use a block size of 2 (bytes), then passes two bytes in and receives a result of two bytes. Based on the reasoning I mention in my reply to Ivan below, I'm assuming it doesn't use some implicit padding. To be on the safe side, I've tried a 64-bit block size in C# with all available padding types and haven't received the expected result. – iddqd Jun 28 '12 at 14:34
  • DES is not defined on such block sizes. Padding is not the same as block size. You cannot tune the block size to your liking. It is burned into the algorithm. – usr Jun 28 '12 at 14:38
  • You need to find out how to use CFB (http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29). I don't know myself but I know that that is what you need. – usr Jun 28 '12 at 14:40
  • Are you sure that the cipher mode is plain CFB and not a combination of CFB+OFB? The latter does AFAIR allow to have a cipher text that is as long as the plain text (no padding). – Robert Jun 28 '12 at 14:43
  • @Robert Unfortunately, I can't test CFB+OFB decryption of the data with .NET's TripleDES, since it's only letting me set one Mode on my provider at a time :( – iddqd Jun 28 '12 at 17:40

2 Answers2

2

One possibility is that the last two bytes of the plaintext are simply XORed with the two bytes of the final encrypted cipher block, and the remainder is discarded. It should be simple enough to get this behavior using the .NET classes.

  1. Set the blocksize to 64 bits.
  2. Set the mode to CFB.
  3. Set the feedback size to 64 bits
  4. Pad the input to be a multiple of 8 bytes. It doesn't matter what padding you use because you are going to throw away the extra data.
  5. Transform the blocks.
  6. Throw away the residue.
President James K. Polk
  • 40,516
  • 21
  • 95
  • 125
  • That's gotten me halfway there. The first byte seems to decrypt properly every time with this approach, but the second byte still isn't lining up. I've tried various padding schemes just in case, but none seem to make an impact. The only difference between my test code and what you lay out is that I had to set feedback to 8 bits, since I receive an exception otherwise (that says it must be 8 bits). Any ideas on what might be going on with that second (and last) byte? – iddqd Jul 06 '12 at 17:12
  • @iddqd: I really don't know, sorry. – President James K. Polk Jul 06 '12 at 21:54
0

Though MSDN says you can set block size through that property, I think it's impossible to set 16-bit block size for 3DES since DES (and 3DES) was created to use 64-bit blocks only.

I guess that legacy software uses some padding scheme for the last block to be encrypted. Usually it's filling the remaining bytes with random values, and saving the number of these not-needed bytes to the last byte.

Ivan Kashtanov
  • 674
  • 4
  • 17
  • Well, the result of the legacy encryption is a total of 26 bytes. So it's spitting out three 8-byte blocks from the "standard" method, and then a 2-byte block from its "remainder method." If it was doing padding on the 2-byte block, wouldn't it pad it to 8 bytes and therefore have an 8-byte result for that portion of the algorithm, resulting in a total of 32 bytes (24+8) instead of 26 (24+2)? From what I understand of these block ciphers, they always return a result that has the same block size as the input, right? Which would include the padding if it was adding it behind the scenes? – iddqd Jun 28 '12 at 14:25
  • There's also CTS (ciphertext stealing) encryption mode which produces ciphertext with the same length as plaintext. It processes 2 last blocks differently than the others (which are encrypted using CBC or ECB). [CipherMode](http://msdn.microsoft.com/en-us/library/system.security.cryptography.ciphermode.aspx) enumeration has CTS member which uses CBC and may be what you need. – Ivan Kashtanov Jun 28 '12 at 17:54