Example #1
0
        public static void Mac()
        {
            var digest = new Blake2bMac(new PinnedMemory <byte>(new byte[] { 63, 61, 77, 20, 63, 61, 77 }, false));

            // This is a common, but could be unsafe example of dealing with strings from a form using text encoding.
            using var exampleHash = new PinnedMemory <byte>(new byte[digest.GetLength()]);
            var unsafeCaw = "caw caw caw";                                                     // this is unsafe because string's can't be pinned and are subject to garbage collection, and being written to disk (pagefile).
            var caw       = new PinnedMemory <byte>(Encoding.UTF8.GetBytes(unsafeCaw), false); // this is now safe but ONLY the variable caw, unsafeCaw is STILL exposed.

            unsafeCaw = string.Empty;                                                          // unsafeCaw COULD STILL exposed even tho we set it to empty because this depends on garbage collection getting around to clearing it.
            digest.UpdateBlock(caw, 0, caw.Length);
            digest.DoFinal(exampleHash, 0);

            Console.WriteLine(BitConverter.ToString(exampleHash.ToArray()));

            // This is a more uncommon but should be safer example of how to use strings with SecureString for input.
            using var exampleHash2 = new PinnedMemory <byte>(new byte[digest.GetLength()]);

            var secureCaw = new SecureString();

            secureCaw.AppendChar('c');
            secureCaw.AppendChar('a');
            secureCaw.AppendChar('w');
            secureCaw.AppendChar(' ');
            secureCaw.AppendChar('c');
            secureCaw.AppendChar('a');
            secureCaw.AppendChar('w');
            secureCaw.AppendChar(' ');
            secureCaw.AppendChar('c');
            secureCaw.AppendChar('a');
            secureCaw.AppendChar('w');
            secureCaw.MakeReadOnly();

            using var pinnedCaw = new PinnedMemory <char>(new char[secureCaw.Length]);
            var cawPointer = Marshal.SecureStringToBSTR(secureCaw);

            for (var i = 0; i <= secureCaw.Length - 1; i++)
            {
                var c = (char)Marshal.ReadByte(cawPointer, i * 2);
                pinnedCaw[i] = c;
            }

            using var pinnedCawBytes = new PinnedMemory <byte>(Encoding.UTF8.GetBytes(pinnedCaw.ToArray()), false);
            digest.UpdateBlock(pinnedCawBytes, 0, secureCaw.Length);
            digest.DoFinal(exampleHash2, 0);
            Console.WriteLine(BitConverter.ToString(exampleHash2.ToArray()));
        }
        private static void Mac()
        {
            // This is an example of hashing byte[] using PinnedMemory. This is the best method as it protects bytes during creation of the mac
            // and not just the output. It will also zero bytes after there written. However, raw byte[] is also accepted as shown in the commented version.
            var digest = new Blake2bMac(new PinnedMemory <byte>(new byte[] { 63, 61, 77, 20, 63, 61, 77 }, false));

            using var exampleHash = new PinnedMemory <byte>(new byte[digest.GetLength()]);

            // digest.UpdateBlock(new byte[] {63, 61, 77, 20, 63, 61, 77, 20, 63, 61, 77}, 0, 11); // This may be exposed without being pinned.
            digest.UpdateBlock(new PinnedMemory <byte>(new byte[] { 63, 61, 77, 20, 63, 61, 77, 20, 63, 61, 77 }, false),
                               0, 11);
            digest.DoFinal(exampleHash, 0);

            Console.WriteLine(BitConverter.ToString(exampleHash.ToArray()));
        }