Esempio n. 1
0
        /// <summary>
        /// 获取处理选项
        /// </summary>
        /// <param name="card"></param>
        public void GPO(ICCard card)
        {
            StringBuilder body    = new StringBuilder();
            List <string> gpoList = new List <string>();

            if (card.GPOL == null || card.GPOL.Count == 0)
            {
                throw new CardReadException("未读取到处理选项列表");
            }
            gpoList = card.GPOL.ToList();
            gpoList.ForEach(pdo => body.Append(PublicStaticData.PDOL[pdo]));
            body.Insert(0, (body.Length / 2).ToString("x2"));
            body.Insert(0, "83");
            body.Insert(0, (body.Length / 2).ToString("x2"));
            APDUEntity       GPO     = new APDUEntity("80", "A8", "00", "00", body.ToString());
            string           result  = CardReader.SendAPDU(GPO.ToString());
            List <TLVEntity> tlvList = TLVHelper.ToTLVEntityList(result);
            TLVEntity        entity  = null;

            if (tlvList != null && tlvList.Count > 0)
            {
                entity = tlvList[0];
            }
            card.AIP = CodeConvert.ToHexString(entity.Value.Take(2).ToArray());//前两位是AIP
            List <string> afl = new List <string>();

            for (int i = 2; i < entity.Value.Length; i = i + 4)
            {
                afl.Add(CodeConvert.ToHexString(entity.Value.Take(i + 4).Skip(i).ToArray()));
            }
            card.AFL = afl;
        }
Esempio n. 2
0
        /// <summary>
        /// 获取应用密文
        /// </summary>
        /// <param name="card">卡片信息</param>
        /// <returns></returns>
        public void GENERATEARQC(ICCard card, string transactionType = TransactionType.Pay)
        {
            PublicStaticData.TransactionType = TransactionType.Pay;
            Random random = new Random();

            PublicStaticData.RadomData = CodeConvert.ToHexString(new byte[] { (byte)random.Next(256), (byte)random.Next(256), (byte)random.Next(256), (byte)random.Next(256) });
            card.RadomData             = PublicStaticData.RadomData;
            StringBuilder cdol1Builder = new StringBuilder();

            card.CDOL1.ToList().ForEach(cdo => cdol1Builder.Append(PublicStaticData.CDOL1[cdo]));
            cdol1Builder.Insert(0, (cdol1Builder.Length / 2).ToString("x2"));
            APDUEntity entity = new APDUEntity("80", "AE", "80", "00", cdol1Builder.ToString());
            string     arqc   = CardReader.SendAPDU(entity.ToString());

            List <TLVEntity> entityList = TLVHelper.ToTLVEntityList(arqc);

            if (entityList.Count == 0)
            {
                throw new CardReadException("获取应用密文(ARQC)失败");
            }
            TLVEntity arqcEntity = entityList[0];

            card.CID            = arqcEntity.Value[0].ToString("x2");                                               //密文信息 L:1
            card.ATC            = CodeConvert.ToHexString(new byte[] { arqcEntity.Value[1], arqcEntity.Value[2] }); //ATC 应用交易计数器 L:2
            card.AC             = CodeConvert.ToHexString(arqcEntity.Value.Take(11).Skip(3).ToArray());             //AC应用密文 L:8
            card.IssBankAppData = CodeConvert.ToHexString(arqcEntity.Value.Skip(11).ToArray());                     //发卡行应用数据
        }
Esempio n. 3
0
        /// <summary>
        /// TLV报文打包
        /// </summary>
        /// <param name="buffer">字节数据</param>
        /// <returns></returns>
        public static List <TLVEntity> Construct(byte[] buffer)
        {
            List <TLVEntity> resultList = new List <TLVEntity>();
            int currentIndex            = 0;

            while (currentIndex < buffer.Length)
            {
                TLVEntity entity = new TLVEntity();
                //1. 根据Tag判断数据是否是嵌套的TLV
                bool hasSubEntity = HasSubEntity(buffer, currentIndex);

                #region Tag解析
                entity.Tag    = GetTag(buffer, currentIndex);
                currentIndex += entity.Tag.Length;
                #endregion

                #region Length解析
                entity.Length = GetLength(buffer, currentIndex);
                currentIndex += entity.Length.Length;
                #endregion

                #region Value解析
                int valueLength = GetValueLengthByLengthByteValue(entity.Length);
                entity.Value = buffer.Take(currentIndex + valueLength).Skip(currentIndex).ToArray();
                if (hasSubEntity)                                  //判断是否是嵌套结构
                {
                    entity.SubTLVEntity = Construct(entity.Value); //嵌套结构递归解析
                }
                currentIndex += entity.Value.Length;
                #endregion

                resultList.Add(entity);
            }
            return(resultList);
        }
Esempio n. 4
0
        /// <summary>
        /// 根据tag获取tlv的值
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="tag"></param>
        /// <returns></returns>
        public static TLVEntity GetValueByTag(List <TLVEntity> entities, string tag)
        {
            TLVEntity resultEntity = null;
            var       query        = entities.SingleOrDefault(e => CodeConvert.ToHexString(e.Tag).ToUpper() == tag);

            if (query == null)
            {
                foreach (var tlv in entities)
                {
                    if (tlv.SubTLVEntity != null)
                    {
                        TLVEntity result = GetValueByTag(tlv.SubTLVEntity, tag);

                        if (result != null && result.Length.Length > 0)
                        {
                            return(result);
                        }
                    }
                }
            }
            else
            {
                resultEntity = query;
            }
            return(resultEntity);
        }
Esempio n. 5
0
        /// <summary>
        /// 解析TLV
        /// </summary>
        /// <param name="list">
        /// <returns></returns>
        public static byte[] Parse(List <TLVEntity> list)
        {
            byte[] buffer          = new byte[4096];
            int    currentIndex    = 0;
            int    currentTLVIndex = 0;
            int    valueSize       = 0;

            while (currentTLVIndex < list.Count())
            {
                valueSize = 0;
                TLVEntity entity = list[currentTLVIndex];

                Array.Copy(entity.Tag, 0, buffer, currentIndex, entity.TagSize);     //解析Tag

                    currentIndex += entity.TagSize;

                for (int index = 0; index < entity.LengthSize; index++)
                {
                    valueSize += entity.Length[index] << (index * 8); //计算Length域的长度
                }
                if (valueSize > 127)
                {
                    buffer[currentIndex] = Convert.ToByte(0x80 | entity.LengthSize);
                    currentIndex        += 1;
                }

                Array.Copy(entity.Length, 0, buffer, currentIndex, entity.LengthSize);   //解析Length

                    currentIndex += entity.LengthSize;
                //判断是否包含子嵌套TLV
                if (entity.SubTLVEntity == null)
                {
                    Array.Copy(entity.Value, 0, buffer, currentIndex, valueSize);    //解析Value
                        currentIndex += valueSize;
                }
                else
                {
                    byte[] tempBuffer = Parse(entity.SubTLVEntity);
                    Array.Copy(tempBuffer, 0, buffer, currentIndex, tempBuffer.Length); //解析子嵌套TLV
                    currentIndex += tempBuffer.Length;
                }

                currentTLVIndex++;
            }

            byte[] resultBuffer = new byte[currentIndex];
            Array.Copy(buffer, 0, resultBuffer, 0, currentIndex);

            return(resultBuffer);
        }
Esempio n. 6
0
        /// <summary>
        /// 发卡行外部认证
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public bool IssueBankAuthenticate(string data)
        {
            //支付成功获取发卡行返回的55域数据
            byte[]           part55Data = CodeConvert.HexStringToByteArray(data);
            List <TLVEntity> tlvList    = TLVPackage.Construct(part55Data);
            TLVEntity        entity     = TLVHelper.GetValueByTag(tlvList, "91");//获取发卡行认证数据

            if (entity != null)
            {
                APDUEntity apdu   = new APDUEntity("00", "82", "00", "00", CodeConvert.ToHexString(entity.Length) + CodeConvert.ToHexString(entity.Value));
                string     result = CardReader.SendAPDU(apdu.ToString());
                return(true);// result.Equals(StatusCode.Success) == result.Equals(StatusCode.Authenticated);
            }
            else
            {
                return(true);
            }
        }