public static KerberosMICToken Decode(byte[] data)
        {
            var result = new KerberosMICToken();
            int offset = 0;

            result.Header    = TypeMarshal.ToStruct <KerberosMICTokenHeader>(data, ref offset);
            result.SGN_CKSUM = data.Skip(offset).ToArray();
            return(result);
        }
        public static KerberosMICToken GSS_GetMIC(KerberosMICToken_Flags_Values flags, long sequenceNumber, ChecksumType type, byte[] key, byte[] data)
        {
            var applicableChecksumType = new List <ChecksumType>()
            {
                ChecksumType.hmac_sha1_96_aes128,
                ChecksumType.hmac_sha1_96_aes256
            };

            if (!applicableChecksumType.Any(checksumType => checksumType == type))
            {
                throw new InvalidOperationException("The checksum type is not applicable!");
            }

            var obj = new KerberosMICToken();

            obj.Header.TOK_ID = KerberosMICToken_TOK_ID_Values.GSS_GetMIC;
            obj.Header.Flags  = flags;
            obj.Header.Filler = new byte[5] {
                0xFF, 0xFF, 0xFF, 0xFF, 0xFF
            };
            obj.Header.SND_SEQ = sequenceNumber;

            var headerBytes = TypeMarshal.ToBytes(obj.Header);

            var checksumData = data.Concat(headerBytes).ToArray();

            int usage;

            if (flags.HasFlag(KerberosMICToken_Flags_Values.SentByAcceptor))
            {
                usage = (int)TokenKeyUsage.KG_USAGE_ACCEPTOR_SIGN;
            }
            else
            {
                usage = (int)TokenKeyUsage.KG_USAGE_INITIATOR_SIGN;
            }

            obj.SGN_CKSUM = KerberosUtility.GetChecksum(key, checksumData, usage, type);

            return(obj);
        }