Ejemplo n.º 1
0
        /// <summary>
        /// 该方法先判断输入的nas信令是否加密,如果没有加密,则直接调用明文解析方法plain()进行解析;
        /// 否则先进行解密,再进行明文解析
        /// </summary>
        /// <param name="nas_pdu">nas信令编码</param>
        /// <param name="direction">该nas信令所在的s1ap信令的方向</param>
        /// <param name="Kasme_1">从diameter信令中获得的Kasme list</param>
        public void decrypt(byte[] nas_pdu, byte direction, List <byte[]> Kasme_1)
        {
            // 清空数据
            cause_str = "";
            byte          proDiscriminator = 0, EBI = 0;
            byte          headType = 0;
            byte          sqn = 0;
            byte          header = 0;
            bool          ciper_or = false;
            byte          down_sqn = 0, up_sqn = 0;
            uint          count  = 0;
            List <byte[]> Kasme1 = new List <byte[]>();

            byte[] Kasme = new byte[32];
            byte[] Knas1 = new byte[32];
            byte[] Knas  = new byte[16];

            proDiscriminator = (byte)(nas_pdu[0] & 0x0f); //指示nas信令类型是ESM or EMM
            if (proDiscriminator == 0x07)                 //EMM 消息
            {
                headType = (byte)((nas_pdu[0] & 0xf0) >> 4);
            }
            else if (proDiscriminator == 0x02)          //ESM消息
            {
                EBI = (byte)((nas_pdu[0] & 0xf0) >> 4); //EPS bear identity
            }
            //用于判断security header Type=2,4时,加密开关是否关闭,若关闭,则不需要进行解密。
            if ((headType == 1) || (headType == 2) || (headType == 3) || (headType == 4)) //当headerType=1,2,3,4时才有nasPlain,sqn,header,ciper_or.
            {
                byte[] nasPlain = new byte[nas_pdu.Length - 6];                           //nasPlain表示加密的nas部分,但是这只适宜于headertype=1,2,3,4的情况,不适于type=0.
                sqn = nas_pdu[5];                                                         //获得每条信令的序列号(对于service request有特殊情况,该表达式不是其序列号,故需要单独处理)
                Array.Copy(nas_pdu, 6, nasPlain, 0, nasPlain.Length);                     //当nas不是plain message时(或者完整性保护,或者加密),去掉nas_pdu安全头部
                //把剩余部分放在nasPlain中。
                header   = nasPlain[0];                                                   //特征字节,指示nas信令是否属于nas  esm 消息
                ciper_or = field(header);                                                 //用于判断是否打开加密开关,如果是true,则加密开关关闭,不加密
                if (headType == 1)                                                        //只进行完整性保护,不加密
                {
                    #region
                    //用于计算加密所使用的参数COUNT
                    if (direction == 0)//方向下行(MME->eNB)
                    {
                        down_sqn = sqn;
                        if (System.Math.Abs(down_sqn - re_down_sqn) >= 128)
                        {
                            down_overflow++;
                        }
                        re_down_sqn = down_sqn;
                        count       = (uint)(down_overflow << 8 | down_sqn); //把溢出值与序列号拼接
                    }
                    if (direction == 1)                                      //方向上行(eNB->MME)
                    {
                        up_sqn = sqn;
                        if (System.Math.Abs(up_sqn - re_up_sqn) >= 128)
                        {
                            down_overflow++;
                        }
                        re_up_sqn = up_sqn;
                        count     = (uint)(up_overflow << 8 | up_sqn);
                    }

                    cause_str   = cause1.NasCause(nasPlain);//解析nas信令中的 cause
                    IndexCause  = cause1.Index;
                    LengthCause = cause1.Length;
                    plain(nasPlain);
                    #endregion
                }
                else if (headType == 2)//完整性保护并加密(是否真的加密还需要判断加密开关是否打开)
                {
                    #region
                    if (direction == 0)
                    {
                        down_sqn = sqn;
                        if (System.Math.Abs(down_sqn - re_down_sqn) >= 128)
                        {
                            down_overflow++;
                        }
                        re_down_sqn = down_sqn;
                        count       = (uint)(down_overflow << 8 | down_sqn);//把溢出值与序列号拼接
                    }
                    if (direction == 1)
                    {
                        up_sqn = sqn;
                        if (System.Math.Abs(up_sqn - re_up_sqn) >= 128)
                        {
                            down_overflow++;
                        }
                        re_up_sqn = up_sqn;
                        count     = (uint)(up_overflow << 8 | up_sqn);
                    }
                    if ((header == 0x07) || (ciper_or == true))//虽然安全头类型为2,但是加密开关关闭故不加密
                    {
                        plain(nasPlain);
                        IndexCause  = cause1.Index;
                        LengthCause = cause1.Length;
                    }
                    else
                    {
                        if (Kasme_1.Count > 0)        //diameter信令分配有根密钥
                        {
                            Kasme = Kasme_1[Kasme_i]; //在此处获得Kasme数组中合适的Kasme
                            //解密模块,注意三种算法的IK是不同的
                            if (algorithm == 1)       //加密算法选择EEA1,即snow 3G,下面的解密方法具体见EEA1和KDF算法的介绍
                            {
                                #region
                                UInt32[] IK1 = new UInt32[4];//存放解密所需的IK值(count,方向,identity组成)
                                if (direction == 0)
                                {
                                    IK1[0] = 0;
                                    IK1[1] = count;
                                    IK1[2] = 0;
                                    IK1[3] = count;
                                }
                                if (direction == 1)
                                {
                                    IK1[0] = 0x04000000;
                                    IK1[1] = count;
                                    IK1[2] = 0x04000000;
                                    IK1[3] = count;
                                }
                                byte[] str = new byte[7] {
                                    0x15, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01
                                };
                                Knas1 = kdf.kdf_decode(Kasme, str);
                                Array.Copy(Knas1, 16, Knas, 0, 16);        //获得Knas
                                nasPlain = eea1.snow(nasPlain, Knas, IK1); //解析出明文
                                #endregion
                            }
                            else if (algorithm == 2)//加密算法选择EEA2,即AES,下面的解密方法具体见EEA2和KDF算法的介绍
                            {
                                #region
                                byte[] count1 = new byte[4];
                                count1 = uintToBytes(count);
                                byte[] diret = new byte[4];//用于表示direction部分
                                byte[] IK    = new byte[16];
                                //EEA2的IK与EEA1不同
                                if (direction == 0)
                                {
                                    diret[0] = 0;
                                    diret[1] = 0;
                                    diret[2] = 0;
                                    diret[3] = 0;
                                }
                                if (direction == 1)
                                {
                                    diret[0] = 0x04;
                                    diret[1] = 0;
                                    diret[2] = 0;
                                    diret[3] = 0;
                                }
                                Array.Copy(count1, 0, IK, 0, 4);
                                Array.Copy(diret, 0, IK, 4, 4);
                                byte[] str = new byte[7] {
                                    0x15, 0x01, 0x00, 0x01, 0x02, 0x00, 0x01
                                };
                                Knas1 = kdf.kdf_decode(Kasme, str);
                                Array.Copy(Knas1, 16, Knas, 0, 16);      //获得Knas
                                nasPlain = eea2.aes(nasPlain, Knas, IK); //解析明文
                                #endregion
                            }
                            else if (algorithm == 3)//加密算法选择EEA2,即ZUC,下面的解密方法具体见EEA3和KDF算法的介绍
                            {
                                #region
                                byte[] count1 = new byte[4];
                                count1 = uintToBytes(count);
                                byte[] diret = new byte[4];//用于表示direction部分
                                byte[] IK    = new byte[32];
                                if (direction == 0)
                                {
                                    diret[0] = 0;
                                    diret[1] = 0;
                                    diret[2] = 0;
                                    diret[3] = 0;
                                }
                                if (direction == 1)
                                {
                                    diret[0] = 0x04;
                                    diret[1] = 0;
                                    diret[2] = 0;
                                    diret[3] = 0;
                                }
                                //注意三种算法的IK计算方法不同(程序中的算法有待实际验证)
                                Array.Copy(diret, 0, IK, 0, 4);
                                Array.Copy(count1, 0, IK, 4, 4);
                                Array.Copy(diret, 0, IK, 8, 4);
                                Array.Copy(count1, 0, IK, 12, 4);
                                byte[] str = new byte[7] {
                                    0x15, 0x01, 0x00, 0x01, 0x03, 0x00, 0x01
                                };
                                Knas1 = kdf.kdf_decode(Kasme, str);
                                Array.Copy(Knas1, 16, Knas, 0, 16);//获得Knas
                                nasPlain = eea3.zuc(nasPlain, Knas, IK);
                                #endregion
                            }
                            plain(nasPlain);
                            IndexCause  = cause1.Index;
                            LengthCause = cause1.Length;
                            cause_str   = cause1.NasCause(nasPlain);
                        }
                        else//没有从S6a口获得密钥
                        {
                            identity   = "";
                            cause_str  = "";
                            ue_ip      = "";
                            EsmMessage = "ciperd message";
                        }
                    }

                    #endregion
                }
                else if (headType == 3)//只进行保证性保护
                {
                    #region
                    down_sqn      = 0;
                    down_overflow = 0;
                    count         = (uint)(down_overflow << 8 | down_sqn);
                    cause_str     = cause1.NasCause(nasPlain);
                    plain(nasPlain);
                    IndexCause  = cause1.Index;
                    LengthCause = cause1.Length;
                    #endregion
                }
                else if (headType == 4)//使用新的安全上下文中的KASME加密,故在这里需要更新加密密钥
                {
                    #region
                    up_sqn      = 0;
                    up_overflow = 0;
                    count       = (uint)(up_overflow << 8 | up_sqn);
                    if ((header == 0x07) || (ciper_or == true))//虽然安全头类型为4,但是不加密
                    {
                        plain(nasPlain);
                        cause_str   = cause1.NasCause(nasPlain);
                        IndexCause  = cause1.Index;
                        LengthCause = cause1.Length;
                    }
                    else
                    //解密模块,注意三种算法的IK是不同的
                    {
                        //只有需要解密时,才能更改或获得Kasme,因为即使headType==2,4也不一定会加密,也与加密开关有关系
                        Kasme_i++;//当headertype==4时,要更新Kasme
                        if (Kasme_1.Count > 0)
                        {
                            Kasme = Kasme_1[Kasme_i];//在此处获得Kasme数组中合适的Kasme
                            #region
                            if (algorithm == 1)
                            {
                                #region
                                UInt32[] IK1 = new UInt32[4];//存放解密所需的IK值(count,方向,identity组成)
                                if (direction == 0)
                                {
                                    IK1[0] = 0;
                                    IK1[1] = count;
                                    IK1[2] = 0;
                                    IK1[3] = count;
                                }
                                if (direction == 1)
                                {
                                    IK1[0] = 0x04000000;
                                    IK1[1] = count;
                                    IK1[2] = 0x04000000;
                                    IK1[3] = count;
                                }
                                byte[] str = new byte[7] {
                                    0x15, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01
                                };
                                Knas1 = kdf.kdf_decode(Kasme, str);
                                Array.Copy(Knas1, 16, Knas, 0, 16);        //获得Knas
                                nasPlain = eea1.snow(nasPlain, Knas, IK1); //解析出明文
                                #endregion
                            }
                            else if (algorithm == 2)
                            {
                                #region
                                byte[] count1 = new byte[4];
                                count1 = uintToBytes(count);
                                byte[] diret = new byte[4];//用于表示direction部分
                                byte[] IK    = new byte[16];
                                //EEA2的IK与EEA1不同
                                if (direction == 0)
                                {
                                    diret[0] = 0;
                                    diret[1] = 0;
                                    diret[2] = 0;
                                    diret[3] = 0;
                                }
                                if (direction == 1)
                                {
                                    diret[0] = 0x04;
                                    diret[1] = 0;
                                    diret[2] = 0;
                                    diret[3] = 0;
                                }
                                Array.Copy(count1, 0, IK, 0, 4);
                                Array.Copy(diret, 0, IK, 4, 4);
                                byte[] str = new byte[7] {
                                    0x15, 0x01, 0x00, 0x01, 0x02, 0x00, 0x01
                                };
                                Knas1 = kdf.kdf_decode(Kasme, str);
                                Array.Copy(Knas1, 16, Knas, 0, 16);      //获得Knas
                                nasPlain = eea2.aes(nasPlain, Knas, IK); //解析明文
                                #endregion
                            }
                            else if (algorithm == 3)
                            {
                                #region
                                byte[] count1 = new byte[4];
                                count1 = uintToBytes(count);
                                byte[] diret = new byte[4];//用于表示direction部分
                                byte[] IK    = new byte[32];
                                if (direction == 0)
                                {
                                    diret[0] = 0;
                                    diret[1] = 0;
                                    diret[2] = 0;
                                    diret[3] = 0;
                                }
                                if (direction == 1)
                                {
                                    diret[0] = 0x04;
                                    diret[1] = 0;
                                    diret[2] = 0;
                                    diret[3] = 0;
                                }
                                //注意三种算法的IK计算方法不同(程序中的算法有待实际验证)
                                Array.Copy(diret, 0, IK, 0, 4);
                                Array.Copy(count1, 0, IK, 4, 4);
                                Array.Copy(diret, 0, IK, 8, 4);
                                Array.Copy(count1, 0, IK, 12, 4);
                                byte[] str = new byte[7] {
                                    0x15, 0x01, 0x00, 0x01, 0x03, 0x00, 0x01
                                };
                                Knas1 = kdf.kdf_decode(Kasme, str);
                                Array.Copy(Knas1, 16, Knas, 0, 16);//获得Knas
                                nasPlain = eea3.zuc(nasPlain, Knas, IK);
                                #endregion
                            }
                            //decrypt2();//解密函数(密钥更新)
                            #endregion
                            plain(nasPlain);
                            cause_str   = cause1.NasCause(nasPlain);
                            IndexCause  = cause1.Index;
                            LengthCause = cause1.Length;
                        }
                        else //没有从S6a口获得密钥
                        {
                            identity   = "";
                            cause_str  = "";
                            ue_ip      = "";
                            EsmMessage = "ciperd message";
                        }
                    }
                    #endregion
                }
                //因为此处还要包括安全头部的6字节
                IndexEsm      = IndexEsm + 6;
                IndexEmm      = IndexEmm + 6;
                IndexCause    = IndexCause + 6;
                IndexIP       = IndexIP + 6;
                IndexIdentity = IndexIdentity + 6;
            }
            else if (headType == 0)//不加密,也不进行完整性保护
            {
                plain(nas_pdu);
                cause_str = cause1.NasCause(nas_pdu);
            }
            else //此处表示其余的情况全部视为service request
            {
                #region
                sqn = (byte)(nas_pdu[1] & 0x1f);//service request 的序列号获取
                if (direction == 0)
                {
                    down_sqn = sqn;
                    if (System.Math.Abs(down_sqn - re_down_sqn) >= 128)
                    {
                        down_overflow++;
                    }
                    re_down_sqn = down_sqn;
                    count       = (uint)(down_overflow << 8 | down_sqn);//把溢出值与序列号拼接
                }
                if (direction == 1)
                {
                    up_sqn = sqn;
                    if (System.Math.Abs(up_sqn - re_up_sqn) >= 128)
                    {
                        down_overflow++;
                    }
                    re_up_sqn = up_sqn;
                    count     = (uint)(up_overflow << 8 | up_sqn);
                }
                IndexEsm   = 0;
                LengthEmm  = 1;
                EsmMessage = "service request";
                esmType    = 255;//由于service request既不是EMM消息也不是ESM消息,故没有其编号,暂定为255.
                #endregion
            }
        }
Ejemplo n.º 2
0
        public void decrypt(byte[] nas_pdu, int direction, List <byte[]> kasme)//数组nas_pdu 是nas数据流
        {
            cause_str = "";
            byte          proDiscriminator = 0, EBI = 0;
            byte          headType1 = 0, headType = 0;
            byte          sqn = 0;
            byte          header = 0;
            bool          ciper_or = false;
            byte          down_sqn = 0, up_sqn = 0;
            uint          count  = 0;
            List <byte[]> Kasme1 = new List <byte[]>();

            byte[] Kasme = new byte[32];


            byte[] Knas1 = new byte[32];
            byte[] Knas  = new byte[16];

            proDiscriminator = (byte)(nas_pdu[0] & 0x0f);
            if (proDiscriminator == 0x07)
            {
                headType1 = (byte)((nas_pdu[0] & 0xf0) >> 4);
            }
            else if (proDiscriminator == 0x02)
            {
                EBI = (byte)((nas_pdu[0] & 0xf0) >> 4);
            }



            //用于判断security header Type=2,4时,加密开关是否关闭,若关闭,则不需要进行解密。
            if ((headType1 == 1) || (headType1 == 2) || (headType1 == 3) || (headType1 == 4)) //当headerType=1,2,3,4时才有nasPlain,sqn,header,ciper_or.
            {
                byte[] nasPlain = new byte[nas_pdu.Length - 6];                               //nasPlain表示加密的nas部分,但是这只适宜于headertype=1,2,3,4的情况,不适于type=0.
                sqn = nas_pdu[5];                                                             //获得每条信令的序列号(对于service request有特殊情况,该表达式不是其序列号,故需要单独处理)
                Array.Copy(nas_pdu, 6, nasPlain, 0, nasPlain.Length);
                header   = nasPlain[0];
                ciper_or = field(header);
                if (headType1 == 1)
                {
                    #region
                    if (direction == 0)
                    {
                        down_sqn = sqn;
                        if (System.Math.Abs(down_sqn - re_down_sqn) >= 128)
                        {
                            down_overflow++;
                        }
                        re_down_sqn = down_sqn;
                        count       = (uint)(down_overflow << 8 | down_sqn);//把溢出值与序列号拼接
                    }
                    if (direction == 1)
                    {
                        up_sqn = sqn;
                        if (System.Math.Abs(up_sqn - re_up_sqn) >= 128)
                        {
                            down_overflow++;
                        }
                        re_up_sqn = up_sqn;
                        count     = (uint)(up_overflow << 8 | up_sqn);
                    }
                    cause_str = cause1.NasCause(nasPlain);
                    plain(nasPlain);
                    #endregion
                }
                else if (headType1 == 2)
                {
                    #region
                    if (direction == 0)
                    {
                        down_sqn = sqn;
                        if (System.Math.Abs(down_sqn - re_down_sqn) >= 128)
                        {
                            down_overflow++;
                        }
                        re_down_sqn = down_sqn;
                        count       = (uint)(down_overflow << 8 | down_sqn);//把溢出值与序列号拼接
                    }
                    if (direction == 1)
                    {
                        up_sqn = sqn;
                        if (System.Math.Abs(up_sqn - re_up_sqn) >= 128)
                        {
                            down_overflow++;
                        }
                        re_up_sqn = up_sqn;
                        count     = (uint)(up_overflow << 8 | up_sqn);
                    }
                    if ((header == 0x07) || (ciper_or == true))//虽然安全头类型为2,但是不加密
                    {
                        plain(nasPlain);
                    }
                    else
                    {
                        if (kasme.Count > 0)
                        {
                            //Kasme1 = convert(Kasme_1);//将string的Kasme转为byte数组
                            Kasme = kasme[MainForm.kasmeCount];//在此处获得Kasme数组中合适的Kasme
                            //解密模块,注意三种算法的IK是不同的
                            if (algorithm == 1)
                            {
                                #region
                                UInt32[] IK1 = new UInt32[4];//存放解密所需的IK值(count,方向,identity组成)
                                if (direction == 0)
                                {
                                    IK1[0] = 0;
                                    IK1[1] = count;
                                    IK1[2] = 0;
                                    IK1[3] = count;
                                }
                                if (direction == 1)
                                {
                                    IK1[0] = 0x04000000;
                                    IK1[1] = count;
                                    IK1[2] = 0x04000000;
                                    IK1[3] = count;
                                }
                                byte[] str = new byte[7] {
                                    0x15, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01
                                };
                                Knas1 = kdf.kdf_decode(Kasme, str);
                                Array.Copy(Knas1, 16, Knas, 0, 16);        //获得Knas
                                nasPlain = eea1.snow(nasPlain, Knas, IK1); //解析出明文
                                #endregion
                            }
                            else if (algorithm == 2)
                            {
                                #region
                                byte[] count1 = new byte[4];
                                count1 = uintToBytes(count);
                                byte[] diret = new byte[4];//用于表示direction部分
                                byte[] IK    = new byte[16];
                                //EEA2的IK与EEA1不同
                                if (direction == 0)
                                {
                                    diret[0] = 0;
                                    diret[1] = 0;
                                    diret[2] = 0;
                                    diret[3] = 0;
                                }
                                if (direction == 1)
                                {
                                    diret[0] = 0x04;
                                    diret[1] = 0;
                                    diret[2] = 0;
                                    diret[3] = 0;
                                }
                                Array.Copy(count1, 0, IK, 0, 4);
                                Array.Copy(diret, 0, IK, 4, 4);
                                byte[] str = new byte[7] {
                                    0x15, 0x01, 0x00, 0x01, 0x02, 0x00, 0x01
                                };
                                Knas1 = kdf.kdf_decode(Kasme, str);
                                Array.Copy(Knas1, 16, Knas, 0, 16);      //获得Knas
                                nasPlain = eea2.aes(nasPlain, Knas, IK); //解析明文
                                #endregion
                            }
                            else if (algorithm == 3)
                            {
                                #region
                                byte[] count1 = new byte[4];
                                count1 = uintToBytes(count);
                                byte[] diret = new byte[4];//用于表示direction部分
                                byte[] IK    = new byte[32];
                                if (direction == 0)
                                {
                                    diret[0] = 0;
                                    diret[1] = 0;
                                    diret[2] = 0;
                                    diret[3] = 0;
                                }
                                if (direction == 1)
                                {
                                    diret[0] = 0x04;
                                    diret[1] = 0;
                                    diret[2] = 0;
                                    diret[3] = 0;
                                }
                                //注意三种算法的IK计算方法不同(程序中的算法有待实际验证)
                                Array.Copy(diret, 0, IK, 0, 4);
                                Array.Copy(count1, 0, IK, 4, 4);
                                Array.Copy(diret, 0, IK, 8, 4);
                                Array.Copy(count1, 0, IK, 12, 4);
                                byte[] str = new byte[7] {
                                    0x15, 0x01, 0x00, 0x01, 0x03, 0x00, 0x01
                                };
                                Knas1 = kdf.kdf_decode(Kasme, str);
                                Array.Copy(Knas1, 16, Knas, 0, 16);//获得Knas
                                nasPlain = eea3.zuc(nasPlain, Knas, IK);
                                #endregion
                            }
                            plain(nasPlain);
                            cause_str = cause1.NasCause(nasPlain);
                        }
                        else//没有获得密钥
                        {
                            identity  = "";
                            cause_str = "";
                            ue_ip     = "";
                            str2      = "ciperd message";
                        }
                    }

                    #endregion
                }
                else if (headType1 == 3)
                {
                    #region
                    down_sqn      = 0;
                    down_overflow = 0;
                    count         = (uint)(down_overflow << 8 | down_sqn);
                    cause_str     = cause1.NasCause(nasPlain);
                    plain(nasPlain);
                    #endregion
                }
                else if (headType1 == 4)
                {
                    #region

                    up_sqn      = 0;
                    up_overflow = 0;
                    count       = (uint)(up_overflow << 8 | up_sqn);
                    if ((header == 0x07) || (ciper_or == true))//虽然安全头类型为4,但是不加密
                    {
                        plain(nasPlain);
                    }
                    else
                    //解密模块,注意三种算法的IK是不同的
                    {
                        //只有需要解密时,才能更改或获得Kasme,因为即使headType==2,4也不一定会加密,也与加密开关有关系
                        MainForm.kasmeCount++;//当headertype==4时,要更新Kasme
                        if (kasme.Count > 0)
                        {
                            //Kasme1 = convert(Kasme_1);//将string的Kasme转为byte数组
                            Kasme = kasme[MainForm.kasmeCount];//在此处获得Kasme数组中合适的Kasme
                            #region
                            if (algorithm == 1)
                            {
                                #region
                                UInt32[] IK1 = new UInt32[4];//存放解密所需的IK值(count,方向,identity组成)
                                if (direction == 0)
                                {
                                    IK1[0] = 0;
                                    IK1[1] = count;
                                    IK1[2] = 0;
                                    IK1[3] = count;
                                }
                                if (direction == 1)
                                {
                                    IK1[0] = 0x04000000;
                                    IK1[1] = count;
                                    IK1[2] = 0x04000000;
                                    IK1[3] = count;
                                }
                                byte[] str = new byte[7] {
                                    0x15, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01
                                };
                                Knas1 = kdf.kdf_decode(Kasme, str);
                                Array.Copy(Knas1, 16, Knas, 0, 16);        //获得Knas
                                nasPlain = eea1.snow(nasPlain, Knas, IK1); //解析出明文
                                #endregion
                            }
                            else if (algorithm == 2)
                            {
                                #region
                                byte[] count1 = new byte[4];
                                count1 = uintToBytes(count);
                                byte[] diret = new byte[4];//用于表示direction部分
                                byte[] IK    = new byte[16];
                                //EEA2的IK与EEA1不同
                                if (direction == 0)
                                {
                                    diret[0] = 0;
                                    diret[1] = 0;
                                    diret[2] = 0;
                                    diret[3] = 0;
                                }
                                if (direction == 1)
                                {
                                    diret[0] = 0x04;
                                    diret[1] = 0;
                                    diret[2] = 0;
                                    diret[3] = 0;
                                }
                                Array.Copy(count1, 0, IK, 0, 4);
                                Array.Copy(diret, 0, IK, 4, 4);
                                byte[] str = new byte[7] {
                                    0x15, 0x01, 0x00, 0x01, 0x02, 0x00, 0x01
                                };
                                Knas1 = kdf.kdf_decode(Kasme, str);
                                Array.Copy(Knas1, 16, Knas, 0, 16);      //获得Knas
                                nasPlain = eea2.aes(nasPlain, Knas, IK); //解析明文
                                #endregion
                            }
                            else if (algorithm == 3)
                            {
                                #region
                                byte[] count1 = new byte[4];
                                count1 = uintToBytes(count);
                                byte[] diret = new byte[4];//用于表示direction部分
                                byte[] IK    = new byte[32];
                                if (direction == 0)
                                {
                                    diret[0] = 0;
                                    diret[1] = 0;
                                    diret[2] = 0;
                                    diret[3] = 0;
                                }
                                if (direction == 1)
                                {
                                    diret[0] = 0x04;
                                    diret[1] = 0;
                                    diret[2] = 0;
                                    diret[3] = 0;
                                }
                                //注意三种算法的IK计算方法不同(程序中的算法有待实际验证)
                                Array.Copy(diret, 0, IK, 0, 4);
                                Array.Copy(count1, 0, IK, 4, 4);
                                Array.Copy(diret, 0, IK, 8, 4);
                                Array.Copy(count1, 0, IK, 12, 4);
                                byte[] str = new byte[7] {
                                    0x15, 0x01, 0x00, 0x01, 0x03, 0x00, 0x01
                                };
                                Knas1 = kdf.kdf_decode(Kasme, str);
                                Array.Copy(Knas1, 16, Knas, 0, 16);//获得Knas
                                nasPlain = eea3.zuc(nasPlain, Knas, IK);
                                #endregion
                            }
                            //decrypt2();//解密函数(密钥更新)
                            #endregion
                            plain(nasPlain);
                            cause_str = cause1.NasCause(nasPlain);
                        }
                        else //没有从S6a口获得密钥
                        {
                            identity  = "";
                            cause_str = "";
                            ue_ip     = "";
                            str2      = "ciperd message";
                        }
                    }
                    #endregion
                }
            }
            else if (headType1 == 0) //不加密
            {
                plain(nas_pdu);      //注意函数中的参数是nas_pdu,与上面的nasPlain不同
                cause_str = cause1.NasCause(nas_pdu);
            }
            else //此处表示其余的情况全部视为service request
            {
                #region
                sqn = (byte)(nas_pdu[1] & 0x1f);//service request 的序列号获取
                if (direction == 0)
                {
                    down_sqn = sqn;
                    if (System.Math.Abs(down_sqn - re_down_sqn) >= 128)
                    {
                        down_overflow++;
                    }
                    re_down_sqn = down_sqn;
                    count       = (uint)(down_overflow << 8 | down_sqn);//把溢出值与序列号拼接
                }
                if (direction == 1)
                {
                    up_sqn = sqn;
                    if (System.Math.Abs(up_sqn - re_up_sqn) >= 128)
                    {
                        down_overflow++;
                    }
                    re_up_sqn = up_sqn;
                    count     = (uint)(up_overflow << 8 | up_sqn);
                }
                str2    = "service request";
                esmType = 255;//由于service request既不是EMM消息也不是ESM消息,故没有其编号,暂定为255.
                #endregion
            }
        }