This is a common question: You receive encrypted data and a key and want to decrypt. The person providing the encrypted data has provided little information, perhaps only that the encryption algorithm is AES. Where to do you begin, and what additional information, if any, do you need?

Answer:

AES encryption comes in 3 key sizes: 128-bit, 192-bit, and 256-bit. Look at the key you received. Which of the following does it look like:

  1. zxcv1234abcdQWER
  2. 7A786376313233346162636451574552
  3. enhjdjEyMzRhYmNkUVdFUg==

The strings above are all the same key encoded differently.

#1 is a us-ascii string that is exactly 16 characters.  This is a clue that the person gave you a 128-bit key (16 bytes * 8 bits/byte = 128) and that the bytes used for the key are the ascii values of the characters in the string.

#2 is a hexidecimal representation of #1.  If you have a hexidecimal representation of the key, you’ll notice that only the characters 0-9 and A-F (or a-f) are used.  Each byte of the key is represented by 2 ascii bytes.  If your hex string is 32 characters, you have a 16-byte key (and therefore 128-bit encryption).

#3 is a base64 encoded representation of #1.  The tell-tale signs of Base64 are:  It is often a string ending in “=” or “==”, and it is not a multiple of 16 characters in length, and it uses characters not valid in a hex string.  A base64 string will be about 1/3rd longer than the binary bytes it represents.  Thus it is longer than our ascii representation, but shorter than the hex representation.  Therfore, if it’s between 16 and 32 bytes, you can guess 128-bit encryption.  if longer than 32-bytes, it’s 256-bit encryption.

So… once you understand the key, you can set the KeyLength and secret key:

cryptObject.KeyLength = 128;

// If the key is represented as an ascii string:
cryptObject.SetEncodedKey(keyStr, "ascii");

// If the key is represented as an hexidecimal string:
cryptObject.SetEncodedKey(keyStr, "hex");

// If the key is represented as an base64 string:
cryptObject.SetEncodedKey(keyStr, "base64");

OK, the KeyLength and the secret key are specified. What’s left?
You need to know the following:

  • CBC or ECB mode?
  • If CBC mode, what is the initialization vector (IV)
  • Padding scheme?
  • Format of your encrypted data?

Chances are more likely that it is CBC mode (which stands for cipher block chaining).  If so, you need an initialization vector.  This will always be 16 bytes long, regardless of the key length.  If no IV is provided, then it’s probable that it is assumed to be all NULL bytes, and this is the default w/ the Chilkat component.

If you have the IV, then examine it just like you did for the key, and call SetEncodedIV just like you called SetEncodedKey, passing the correct encoding (“ascii”, “hex”, or “base64”) for the 2nd argument.

If ECB mode is used, then set the CipherMode property = “ecb”

cryptObject.CipherMode = "ecb";

The PaddingScheme property may be initially left at the default value (which is the most commonly used).  My suggestion is to test with an amount of data that is more than 16 bytes.  The reason is that if everything is correct *except* the PaddingScheme, then your decrypted output will be correct except for the very last 16 bytes.  Once you know that all is correct except for the padding scheme, you can test with different PaddingScheme values.  If you only have a very short amount of data for testing, then it’s not possible to make this distinction.

Finally, look at the encrypted data itself.  Is it hex or base64?  If it is a “string” it must be one or the other.  You’ll want to set the EncodingMode property equal to the encoding of the encrypted data:

cryptObject.EncodingMode = "hex";

Assuming the decrypted result is a string, you’ll call DecryptStringENC.  The “ENC” in the function name indicates that the input is an encoded string and that the encoding is specified by the EncodingMode property.  It returns a string — your decrypted data.

string decryptedStr = cryptObject.DecryptStringENC(encryptedStr);