-3

I have a problem with normal DES encryption in C#, I want an output string with 16 char length (16 bytes 128 bit) that it contains only alphabetic and numeric characters.

Prime
  • 69
  • 2
  • 12
  • 1
    The output length is a function of the input length and padding scheme. You can then encode the output with any appropriate scheme, but if your final alphabet is alphanumeric then you'll have to cope with some expansion. – President James K. Polk May 07 '12 at 10:56
  • How long is your input, in bytes? As @GregS says, you can always encode the output as hex, Base-32 or Base-64 but that will always be more then the number bytes you are encoding. It would also help to know why you need output this length and this format. – rossum May 07 '12 at 11:50

1 Answers1

1

If you are limited to 16-character output consisting only of alphanumeric characters, it means you have ~95 bits of output space available (exactly 96 bits if you could use Base-64 encoding, i.e. include 2 non-alphanumeric characters).

Therefore, nothing you could do would allow you to encrypt more than 95 bits with this restriction. If this is sufficient for you, it is possible.

Something like this (3DES in CTR mode) is an example how it could work (using Base-64), but as stated above in the comments, it really depends on what you really are trying to do.

void Main()
{
    var data = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
    var key = new byte[] { 01, 12, 23, 34, 45, 56, 67, 78, 89, 90, 09, 98, 87, 76, 65, 54, 43, 32, 21, 10, 11, 22, 33, 44 };
    var encrypted = Encrypt(data, key, 0);
    Console.WriteLine(encrypted);
    var decrypted = Decrypt(encrypted, key, 0);
    // decrypted should be equal to data here
}

public string Encrypt(byte[] data, byte[] key, long nonce)
{
    return Convert.ToBase64String(Transform(data, key, nonce));
}

public byte[] Decrypt(string data, byte[] key, long nonce)
{
    return Transform(Convert.FromBase64String(data), key, nonce);
}

byte[] Transform(byte[] data, byte[] key, long nonce)
{
    if (data.Length > 96/8) throw new ArgumentException("Too much data");

    using (var des = new TripleDESCryptoServiceProvider())
    {
        des.Key = key;
        des.Mode = CipherMode.ECB;
        using (var encryptor = des.CreateEncryptor())
        {
            var output = new byte[data.Length];
            var offset = 0;
            for(int counter = 0; counter <= data.Length / 8; ++counter)
            {
                var counterData = BitConverter.GetBytes(((long)counter) ^ nonce);
                var counterEncryption = new byte[des.BlockSize / 8];
                var counterEncryptionLen = encryptor.TransformBlock(counterData, 0, counterData.Length, counterEncryption, 0);
                Debug.Assert(counterEncryptionLen == counterEncryption.Length);
                for (var i = 0; i < des.BlockSize / 8 && offset < output.Length; ++i, ++offset)
                {
                    output[offset] = (byte)(data[offset] ^ counterEncryption[i]);
                }
            }
            return output;
        }
    }
}
Mormegil
  • 7,955
  • 4
  • 42
  • 77