AES CCM/CBC-MAC ExampleAES is a secret key encryption method, and does not provide authentication of the message. CCM can add to AES by providing an authentication and encrypt block cipher mode [CCM - Counter with CBC-MAC]]. It has two parameters: M which indicates the indicates the size of the integrity check value (ICV) and L which defines the size of the length field in octets. [Theory]. It you want just CBC-MAC, set the IV to zero. The results are then:
|
Outline
With CBC (Cipher Block Chaining)-MAC (Message Authentication Code) we authenticate messages with a secret shared key. If Bob wants to send some text to Al-ice, he encrypts it with a shared key and then sends Alice the message digest (or hash of the message) of this. Alice does the same with the secret key and compares the hash that she gets. If they are the same, then Bob has continued to prove his identity (as only he can have the secret key that Bob and Alice share), and that the message has not been changed.
Overall we encrypted the message with the standard form of AES and then throw away everything apart from the last block, and use this as a fixed-length MAC. If the key is not secret the method provides little in the way of security.
For example, it we have a shared key of "test123" and a message of "hello", the CBC-MAC is 9F63F3A838D17066 (16x4 hex characters is 64-bits), but with "hellp" is it A2CD2D8CBD8E6DAD. Only by knowing the secret key can I determine the correct hash. In AES Cipher Block Chaining (CBC) encryption we use an IV to make sure that the bits differ for the same message. In CBC-MAC the IV is set to zero, whereas with AES-CCM (Counter with CBC-MAC) the IV value is used to change the message digest.
Presentation
Code Used
public string ccmaes(bool encrypt, string plain, string key, string iv) { int i = 0; try { try { i = System.Convert.ToInt32(iv); } catch { } byte[] iv_vector = new byte[15]; byte[] key_byte = new byte[32]; byte[] input_buffer = null; byte[] output_buffer = null; byte[] temp_iv = BitConverter.GetBytes(i); for (int val = 0; val < temp_iv.Length; val++) iv_vector[val] = temp_iv[val]; byte[] temp_key = System.Text.Encoding.ASCII.GetBytes(key); for (int val = 0; val < temp_key.Length; val++) key_byte[val] = temp_key[val]; if (encrypt == true) { input_buffer = System.Text.Encoding.ASCII.GetBytes(plain); } else { input_buffer = StringToByteArray(plain); } var param = new AeadParameters(new KeyParameter(key_byte), 64, iv_vector, new byte[] { }); CcmBlockCipher cipher = new CcmBlockCipher(new AesEngine()); cipher.Init(encrypt, param); output_buffer = new byte[cipher.GetOutputSize(plain.Length)]; var len = cipher.ProcessBytes(input_buffer, 0, input_buffer.Length,output_buffer, 0); cipher.DoFinal(output_buffer, len); // Return Hex string for encryption if (encrypt) return Global.ByteToString(output_buffer); // Return string for decrypt UTF8Encoding encoding = new UTF8Encoding(); string str = encoding.GetString(output_buffer); str = str.Replace("\0", string.Empty); return (str); } catch (Exception ex) { encrypted = ex.Message; } return encrypted; }