Annex 1: Routing Cookie Authentication & Encryption The routing cookie is used by Meshcentral to both provide routing information and authenticate that the routing is allowed. The cookie is authenticated using HMAC-SHA256 and encrypted using AES128-CBC. The encoding method takes in a 48
byte long key, the first 32 bytes used for HMAC and the remaining 16 bytes for AES. The initialization vector is The following C code is used to encrypt the routing cookie using AES. The key and the routing instruction and provided as input and the output is a Base secured message. private static string EncodeHttpRoutingCookieEx(
byte
[] key, byte msg)
{ if (key == null || key.Length != 48 || msg == null)
return null MemoryStream mem2 =
MeshUtils
.GetMemoryStream();
// Split the key byte key =
new byte // HMAC
byte
[] key = new byte
// AES
Array
.Copy(key, 0, key, 0, 32);
Array
.Copy(key, 32, key, 0, 16);
//
Select an IVbyte
[] iv = new byte for (int ii < 16; i++) iv[i] = (
byte
)Random.Next(256);
// Setup and perform HMAC-SHA256
using
(
HMACSHA256
hmac = new
HMACSHA256
(key1))
{
High Level Architecture MeshCentral.com
12 byte hmacresult = hmac.ComputeHash(msg); mem2.Write(hmacresult, 0, hmacresult.Length); mem2.Write(msg, 0, msg.Length); msg = mem2.ToArray(); mem2.SetLength(0);
}
// Setup AES128-CBC
byte
[] buf; using (
Rijndael rij = new
RijndaelManaged
())
{ rij.KeySize = 128; rij.Mode =
CipherMode
.CBC; rij.Padding =
PaddingMode
.PKCS7; rij.Key = key rij.IV = iv
// Perform AES128 encrypt using (
MemoryStream mem = new
MemoryStream
())
{ using (
CryptoStream cs = new
CryptoStream
(mem, rij.CreateEncryptor(),
CryptoStreamMode
.Write))
{ cs.Write(msg, 0, msg.Length); cs.FlushFinalBlock(); buf = mem.ToArray();
}
}
}
// Perform formatting mem2.Write(iv, 0, 16); mem2.Write(buf, 0, buf.Length); string r =
"MRC"
+ UrlEscapeBase64(
Convert
.ToBase64String(mem2.ToArray()));
MeshUtils
.RecycleMemoryStream(mem2);
return r } To be compatible with NET 2.0, we use “Rijndael”
instead of AES, but they are identical for our purposes.