0

Is there any good and strong encryption/decryption available which will result always a 512 bit of data value and this value need to be converted to HEX value.

Basically my need is to do this.

ASCII -> HEX Value -> While saving the data I need to encrypt the HEX value which will be another HEX value but will always have only 512 bits of data.

Environment: .NET 4.5, C# and should be compatible with SQL Server 2008 R2 and SQL Server 2012

aioracle
  • 371
  • 2
  • 7
  • 20
  • Well what size is the original data? – Jon Skeet Jun 10 '14 at 05:45
  • At present we have data size of 25 bytes in total (23 numeric and 2 alphanumeric) [AAxxxxxxxxxxxxxxxxxxxxxxx] – aioracle Jun 10 '14 at 06:00
  • Okay, so that sounds feasible - but might you ever have 512 bits of input data (or near that much)? – Jon Skeet Jun 10 '14 at 06:03
  • What we are forecasting the original data might be the max of 30 - 35 bytes as of now but not surely forecasting for full 512 bits at present. – aioracle Jun 10 '14 at 06:09
  • Okay, so can you not pick just about any encryption scheme that will give you less than 512 bits (there are plenty to choose from) and just pad it if necessary? (The ASCII and hex part are somewhat irrelevant - effectively you just have "a small amount of data" and want it encrypted as exactly 512 bits.) – Jon Skeet Jun 10 '14 at 06:16
  • I need to pad the value, but I cannot eliminate the ASCII to HEX conversion as its the application requirement so they can push the value to RFID tags – aioracle Jun 10 '14 at 06:31
  • I wasn't saying you had to eliminate it - but that's a separate matter from the encryption. That's just a text to binary (not actually to hex) conversion, as simple as `Encoding.ASCII.GetBytes(text)`. – Jon Skeet Jun 10 '14 at 06:39
  • Can you add details on what is the input plain data, why do you think you need to encrypt it and when (in what part of you data or control flow) it needs to be encrypted and decrypted? – Oleg Estekhin Jun 10 '14 at 06:43

1 Answers1

1

Modern encryption algorithms always deal with a sequence of bytes, not with symbols. Consider this MSDN example

public static byte[] EncryptString(SymmetricAlgorithm symAlg, string inString)
{
     byte[] inBlock = UnicodeEncoding.Unicode.GetBytes(inString);
     ICryptoTransform xfrm = symAlg.CreateEncryptor();
     byte[] outBlock = xfrm.TransformFinalBlock(inBlock, 0, inBlock.Length);

     return outBlock;
}

In this example the source string is converted to sequence of bytes using Unicode (UTF-16) encoding. This sequence of bytes is encrypted with a symmetric algorithm by TransformFinalBlock() method call.

The important thing here is padding. The MSDN example uses default AES encryption mode setting: CBC mode with random IV and PKCS7 padding. This means that the plain text bytes are processed one AES block (16 bytes) at a time. If the plain text size is not a multiple of 16 bytes the final plain text block is made exactly 16 bytes by adding several bytes to its end. E.g. if the final plain text chunk has 10 bytes, it will be extended by 6 additional bytes. The value of those bytes is the number of bytes added (0x06). If the message length is multiple of 16 bytes a whole padding block will be added. Such block will be filled with value 16 == 0x10.

So with CBC mode and PKCS7 padding 25 plaintext bytes will be always padded to 32 bytes of ciphertext. Have in mind though that IV in this mode should be picked at random for each encrypted string, so the resulting ciphertext must contain 32 + 16 = 48 bytes. In general it is wise to use authenticated encryption. Adding a MAC tag to encrypted text will increase the ciphertext size by additional 16 bytes (at least). So with random IV and MAC the original 25 bytes will become 32 + 16 + 16 = 64 bytes or 512 bits. You will be able to encrypt up to 31 bytes in such way. Encrypting 32..47 bytes will add another block (16 bytes) to the resulting ciphertext.

If such padding mode does not suit your needs you may set padding mode to None and implement your own padding like this:

Aes myAes = Aes.Create();
myAes.Padding = PaddingMode.None;
byte[] plaintext = Encoding.ASCII.GetBytes(text);
//do something with plaintext so that its length becomes multiple of block size:
byte[] paddedPlaintext = MyPaddingScheme(plaintext);
//Encrypt paddedPlaintext using myAes instance

However I must warn you that bad padding scheme might make your encryption insecure. It is always wiser to adapt some existing construct to your needs.

Naturally the ciphertext will not contain ASCII characters only. You may convert it manually to hex byte by byte or use Convert.ToBase64String() to store it in a database column.

Pavel Zhuravlev
  • 2,691
  • 1
  • 18
  • 17
  • Pavel zhuravlev This sounds able, but on introducing MAC tag, could you please provide more information? meanwhile, we shall work on this SymmetricAlgorithm concept and test it out. – aioracle Jun 17 '14 at 04:02
  • @aioracle The standard .Net crypto library contains a selection of MAC generation algorithms. The SHA-based HMACs are pretty good (see `HMACSHA256` class for example). Unfortunately their tag length is longer than 16 bytes (won't fit into 512 bits). Note that you can use some standardized authenticated encryption mode (encryption and MAC in one bundle). The AES-GCM mode may be good for your task. It is not provided in the .Net standard library, so check out this SO question for more options: [link](http://stackoverflow.com/questions/202011/encrypt-and-decrypt-a-string) – Pavel Zhuravlev Jun 19 '14 at 13:29
  • We have successfully managed to implement the solution. ASCII -> Encrypt (32 bits) -> HEX convert. Thanks. I shall look into the MAC generation algorithms at my spare time. Once again Thanks for the pointers. – aioracle Jun 25 '14 at 03:23