Как связаться со смарт-картой, используя команды APDU через последовательный порт, используя c # - PullRequest
0 голосов
/ 06 июля 2018

Я пытался установить связь со смарт-картой EMV на оборудовании для чтения / записи MCR200 через последовательный порт с помощью команд APDU, но все еще безуспешно. Я не получаю и ответа. Вот что я пробовал до сих пор. По крайней мере, я хочу начать с получения ATR карты, прежде чем приступить к чтению и записи записей на смарт-карту.

namespace JappaSmartCard
{
    public partial class BankWrite : Form
    {
        public SerialPort port = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);
        public long bytesRead;
        public byte[] buffer;
        List<byte> bBuffer = new List<byte>();
        string sBuffer = String.Empty;
        private long SendLen, RecvLen;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 262)]
        private byte[] SendBuff;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 262)]
        private byte[] RecvBuff;
        private const int INVALID_SW1SW2 = -450;


        public BankWrite()
        {
            InitializeComponent();
            port.Handshake = Handshake.None;
            port.Encoding = Encoding.ASCII;
            port.ReceivedBytesThreshold = 1;
            //port.ReadTimeout = 5000;
            //port.WriteTimeout = 5000;
            initMenu();

            // Attach a method to be called when there
            // is data waiting in the port's buffer
            port.DataReceived += new SerialDataReceivedEventHandler(verifyChv);


        }

        private void BankWrite_Load(object sender, EventArgs e)
        {
            pbProgress.Visible = false;
        }

        private void initMenu()
        {
            pbProgress.Visible = false;
            btnWrite.Enabled = false;
            btnConnect.Enabled = false;
            btnRead.Enabled = false;
            btnSave.Enabled = false;
            btnUSB.Enabled = false;
            btnFormat.Enabled = false;
            btnError.Enabled = false;
            btnDuplicate.Enabled = false;
            gbSelectHardware.Enabled = false;
            gbDetails.Enabled = false;
            gbTrack1.Enabled = false;
            gbTrack2.Enabled = false;
            gbTrack3.Enabled = false;
            txtAccountNo.Text = "";
            txtFirstName.Text = "";
            txtLastName.Text = "";
            txtPin.Text = "";
            rtbInfo.Text = "";
            rtbTrack1.Text = "";
            rtbTrack2.Text = "";
            rtbTrack3.Text = "";
            ckbARC.Checked = false;
            ckbARQC.Checked = false;
            ckbDDA.Checked = false;
        }

        private void EnableConnectButton()
        {
            btnInitialize.Enabled = false;
            gbSelectHardware.Enabled = true;
            btnConnect.Enabled = true;
        }

        private void ClearBuffers()
        {

        }

        private void DisplayOut(int mType, long msgCode, string PrintText)
        {
            switch (mType)
            {
                case 0: // Notifications only
                    {
                        rtbInfo.SelectionColor = Color.Blue;
                        break;
                    }

                case 1: // PC/SC Error Messages
                    {
                        rtbInfo.SelectionColor = Color.Red;
                        PrintText = Card.GetScardErrMsg(bytesRead);
                        break;
                    }

                case 2: // Input APDU command
                    {
                        rtbInfo.SelectionColor = Color.Black;
                        PrintText = "< " + PrintText;
                        break;
                    }

                case 3: // Output data
                    {
                        rtbInfo.SelectionColor = Color.Green;
                        PrintText = "> " + PrintText;
                        break;
                    }

                case 4: // Notifications on red font
                    {
                        rtbInfo.SelectionColor = Color.Maroon;
                        break;
                    }
            }
            rtbInfo.SelectedText = PrintText + "\r\n";
            rtbInfo.SelectionStart = rtbInfo.TextLength;
            rtbInfo.SelectionColor = Color.Black;
        }

        private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            // Show all the incoming data in the port's buffer
            rtbInfo.Invoke(new EventHandler(delegate { rtbInfo.Text += port.ReadExisting(); }));

            // Use either the binary OR the string technique (but not both)



            // Buffer and process binary data

            while (port.BytesToRead > 0)
                bBuffer.Add((byte)port.ReadByte());
            ProcessBuffer(bBuffer);



            // Buffer string data

            sBuffer += port.ReadExisting();
            ProcessBuffer(sBuffer);
        }

        private void ProcessBuffer(string sBuffer)

        {


        }



        private void ProcessBuffer(List<byte> bBuffer)

        {


        }

        private void btnQuit_Click(object sender, EventArgs e)
        {
            //Application.ExitThread();
            port.Close();
            this.Hide();
        }

        private void btnInitialize_Click(object sender, EventArgs e)
        {
            //Get all the ports attached
            pbProgress.Visible = true;
            pbProgress.Maximum = SerialPort.GetPortNames().Length;
            pbProgress.Step = 1;
            foreach (string s in SerialPort.GetPortNames())
            {
                cboReaders.Items.Add(s);
                pbProgress.PerformStep();
                Console.WriteLine(s);
            }
            cboReaders.Text = "COM1";
            port = new SerialPort(cboReaders.Text,9600, Parity.None, 8, StopBits.One);
            port.Handshake = Handshake.None;
            port.Encoding = Encoding.ASCII;
            port.ReceivedBytesThreshold = 1;
            EnableConnectButton();

        }

        [STAThread]
        private void btnConnect_Click(object sender, EventArgs e)
        {

            if (!port.IsOpen)
                port.Open();
            bytesRead = 0;

            //close All open thread
            //Application.ExitThread();

            // Enter an application loop to keep this thread alive
            //Application.Run();

            pbProgress.Visible = false;
            btnWrite.Enabled = true;
            btnConnect.Enabled = false;
            btnRead.Enabled = true;
            btnSave.Enabled = false;
            btnUSB.Enabled = false;
            btnFormat.Enabled = true;
            // Check if PIN is correct
            port.Write(new byte[] { 0x03, 0x20, 0x00, 0x02, 0x08, 0x31, 0x30, 0x35, 0x34, 0xFF, 0xFF, 0xFF, 0xEE }, 0, 13);
            Console.WriteLine(port.BytesToWrite);
        }

        public void verifyChv(object s, SerialDataReceivedEventArgs e)
        {
            byte[] buffer = new byte[port.ReadBufferSize];
            int bytesRead = port.Read(buffer, 0, buffer.Length);
            foreach (int bf in buffer)
            {
                rtbInfo.Text += bf.ToString("X");
            }
        }

        private string InterpretarHex(object buffer, bool conEspacios = false)
        {
            string sol="";
            object byteAux;

            if (buffer.ToString().Length > 0)
            {
                byteAux = ((int)(Card.Asc((char)((Card.Mid(buffer.ToString(), 1, 1)[0]))))).ToString("X");
                sol = byteAux.ToString();
                for (var i = 2; i <= (buffer.ToString()).Length; i++)
                {
                    byteAux = ((int)(Card.Asc((char)((Card.Mid(buffer.ToString(), i, 1)[0]))))).ToString("X");
                    if ((byteAux.ToString()).Length == 1)
                        byteAux = "0" + byteAux;
                    if ((conEspacios))
                        sol = sol + " " + byteAux;
                    else
                        sol = sol + byteAux;
                }
            }

            return sol;
        }


        private void btnFormat_Click(object sender, EventArgs e)
        {

        }

        private long SendAPDUandDisplay(int SendType, string ApduIn)
        {
            long SendAPDUandDisplay = 0;
            return SendAPDUandDisplay;
        }

        private long SubmitIC()
        {
            long SubmitIC = 0;
            return SubmitIC;
        }

        private long SelectFile(byte HiAddr, byte LoAddr)
        {
            long SelectFile = 0;
            return SelectFile;
        }

        private long readRecord(byte RecNo, byte dataLen)
        {
            long readRecord = 0;
            return readRecord;
        }

        private long writeRecord(int caseType, byte RecNo, byte maxLen, byte dataLen, ref byte[] ApduIn)
        {
            //sample code
            byte[] data = System.Text.ASCIIEncoding.Default.GetBytes("Hello World\n");

            port.Write(data, 0, data.Length);
            return port.BytesToWrite;
        }

        private void cboReaders_SelectedIndexChanged(object sender, EventArgs e)
        {
            if(cboReaders.Items.Count>0)
            {
                if (cboReaders.SelectedIndex >= 0)
                {
                    Console.WriteLine(cboReaders.Text);
                }
                else
                {
                    cboReaders.Text = "COM1";
                }
                port = new SerialPort(cboReaders.Text, 9600, Parity.None, 8, StopBits.One);
                port.Handshake = Handshake.None;
                port.Encoding = Encoding.ASCII;
                port.ReceivedBytesThreshold = 1;
                initMenu();
                EnableConnectButton();
            }
            else
            {
                rtbInfo.Text = "NO SERIAL/COM PORT DEVICE SEEN";
            }
        }
    }
}

1 Ответ

0 голосов
/ 12 июля 2018

Я реализовал платформу EMV с открытым исходным кодом (https://github.com/vicente-da-silva/dcemv).. Она реализует как бесконтактные, так и контактные ядра EMV. Существуют различные драйверы NFC. Вы можете использовать это для связи с картой. Она написана на C #.

...