Mobile payment Smart IC card for NFC communication with Android phone

Source: Internet
Author: User

This article is from http://blog.csdn.net/hellogv/, the citation must be noted!
at present, the common intelligent IC card running Javacard virtual machine, smart IC card can be run by the simplified Java language written by the card application (abbreviation applet). The applet of the Intelligent IC card cannot start itself, must send the Select command to the card by the external terminal (such as POS, Metro Card terminal, etc.), so that the applet,applet of the card can be selected to run. Appplet focuses on data processing, without the expense of I/O functionality. Applet programs have a lifecycle and a designated entry, the most important of which are as follows:
    • public static void Install (byte[] Barray, short boffset, byte blength)

构建了Applet子类的实例,JCRE将会最先调用这个;所有的初始化和分配内存的操作应该在这个里面实现;可以获取卡外实体传进来的一些应用初始化参数。

    • public void process (APDU APDU)
类似于正常java class的main,在安装后,APDU的执行将在这里实现。

    • Protected final void Register ()
applet用来在JCRE中注册该applet实例

    • Register (byte[] Barray, short boffset, byte blength)
register( )功能一样,增加了可以分配其特定的AID的功能。

    • public Boolean Select ()
        JCRE一旦接收到SELECT[by name]命令时,将寻找命令中指示的AID对应的Applet,使之处于活跃状态,接收并处理接下来的APDU命令;在选择新的Applet前,JCRE先调用当前Applet的 deselect 方法;Applet可以拒绝被选择,此时 select 方法返回false;SELECT[by name]命令本身也将传递给applet处理,此时通过 selectingApplet 用以判断当前状态。

        本文的DEMO运行效果如下,包含一个JavaCard的Applet实现和一个Android端的NFC读写程序,实现智能IC卡与Android手机的简单通信。

Next paste a simple applet source code,: http://download.csdn.net/detail/hellogv/8090041.

The general idea is that the applet defines 2 custom commands Cmd_ins_1 and cmd_ins_2 that start with Cmd_cla, when Android phones send Cmd_ins_1 and cmd_ins_ via NFC respectively 2,applet returned to Strhello and Strworld respectively.

The core source code is as follows:

public class MyTest extends Applet {private static final byte[] strhello= {(byte) ' H ', (byte) ' E ', (byte) ' L ', (Byte) ' L ', (byte) ' O '};p rivate static final byte[] Strworld = {(byte) ' W ', (byte) ' O ', (byte) ' R ', (Byte) ' L ', (byte) ' d ',};p rivate static F inal byte Cmd_cla = (byte) 0x80;private static final byte Cmd_ins_1 = (byte) 0x10;private static final byte cmd_ins_2 = (b yte) 0x20;public static void Install (byte[] Barray, short boffset, byte blength) {//gp-compliant Javacard applet Registra Tionnew mytest (). Register (Barray, (short) (Boffset + 1), Barray[boffset]);} /* * Called by Jcre when the Java Card applet is selected. The Java Card applet can define select () to complete initialization, * Otherwise, Jcre calls the parent class's Select (). * @see Javacard.framework.applet#select () */public Boolean select () {short debug=100;debug++;//is used for breakpoint debugging when a select is triggered. return Super.select ();} /* * Called by Jcre when the Java Card applet is discarded. The Java Card applet can define deselect () to complete the purge, * Otherwise, Jcre calls the parent class's deselect (). * @see javacard.framework.applet#deselect () */public void deselect () {Short debug=100;debug++;//for breakpoint debugging Super.deselect ( );}/* * @see javacard.framework.applet#process (Javacard.framework.APDU) */public void process (APDU APDU) is executed every time the APDU command is received {if (Selectingapplet ()) {return;} Get data from external terminals byte[] buffer = Apdu.getbuffer ();//Gets the first bit of data in byte CLA = (byte) (buffer[iso7816. OFFSET_CLA] & 0xFF);//Gets the second bit of data in byte INS = (byte) (buffer[iso7816. Offset_ins] & 0xFF); if (CLA! = CMD_CLA) {//Format not Isoexception.throwit (iso7816.sw_cla_not_supported);} Switch (INS) {case cmd_ins_1:sendbytes (Apdu,strhello); Break;case cmd_ins_2:sendbytes (Apdu,strworld); Break;default : Isoexception.throwit (iso7816.sw_ins_not_supported);}} private void Sendbytes (APDU apdu,byte[] arrays) {byte[] buffer = Apdu.getbuffer (); Short length = (short) arrays.length; Util.arraycopynonatomic (arrays, (short) 0, buffer, (short) 0, [short] length); Apdu.setoutgoingandsend ((short) 0, length );}}


Next, post the core code for Android: http://download.csdn.net/detail/hellogv/8090053.

The approximate idea is that theNFC read-write program on the Android side defines the ID (AID) of 1 applets, the header of the SELECT command (Select_apdu_header),2 custom commands Cmd_ins_1 and cmd_ins_2. First use the aid and select_apdu_header to generate the complete select command, transceive (send) to the card, to start the aid corresponding applet in the card. After starting the applet in the card, theNFC read-write program sends the 2 custom commands inside the Sample_command , and the applet returns "Hello" and "World" respectively.

The core source code is as follows:

Public final class CardReader {private static final String TAG = "Loyaltycardreader";    AID for our loyalty card service.    private static final String Sample_card_aid = "1122001122";    ISO-DEP command HEADER for selecting an AID. Format: [Class | instruction | Parameter 1 |    Parameter 2] private static final String Select_apdu_header = "00a40400"; "OK" status word sent in response to SELECT AID command (0x9000) private static final byte[] select_ok_sw = {(byte)    0x90, (byte) 0x00};    Custom command private static final string[] sample_command={"8010000000",//card received after return "Hello" "8020000000"};//Card received back "world" public static string[][] techlists;public static intentfilter[] Filters;static {try {//the tech lists used to perform M Atching for dispatching of the action_tech_discovered intenttechlists = new string[][] {{IsoDep.class.getName ()}}; FILTERS = new intentfilter[] {new Intentfilter (nfcadapter.action_tech_discovered, "*/*")};}  catch (Exception e) {}}  static public String tagdiscovered (tag tag) {LOG.E (tag, "New tag discovered"); String strresult= ""; ISODEP ISODEP = isodep.get (tag), if (ISODEP! = null) {try {//Connect to the remote NFC deviceisodep.co Nnect ();//Send Select command, the card will return SELECT_OK_SW (byte[) Cmdselect = BUILDSELECTAPDU (Sample_card_aid); LOG.E (TAG, "sending:" + bytearraytohexstring (cmdselect)); byte[] result = isodep.transceive (cmdselect); LOG.E (TAG, "Receive:" + bytearraytohexstring (Result)); byte[][] response = getResponse (result); byte[] Statusword = Response[0];if (Arrays.equals (SELECT_OK_SW, statusword) = = False) return "";//Loop Send custom command for (int i=0;i<sample_ command.length;i++) {String command = Sample_command[i];result = Hexstringtobytearray (command); LOG.E (TAG, "Sending:" + command); result = Isodep.transceive (result); LOG.E (TAG, "Receive:" + bytearraytohexstring (Result)); response = GetResponse (result); byte[] body =response[1]; Strresult=strresult+new String (body) + ":" +bytearraytohexstring (body) + "\ r \ n";} return strresult;} CatcH (IOException e) {log.e (TAG, "Error Communicating with Card:" + e.tostring ());}} return null;} /*** * Decompose the data returned by the card * @param b * @return [0] represents the returned status value, [1] represents the returned body */private static byte[][] GetResponse (byte[] b) {byte[][] ResU lt = new Byte[2][];int length = b.length;byte[] Status = {B[length-2],b[length-1]};byte[] BODY = arrays.copyof (b, le NGTH-2); Result[0]=status;result[1]=body;return result;} public static String load (parcelable parcelable) {//filter out all types of NFC standard data from parcelable final tag tag = (tag) Parcelable;return Tagdis    Covered (tag);} /** * Build APDU for SELECT AID command. This command indicates which service a reader was * interested in communicating with.     See ISO 7816-4.  * * @param aid Application ID (AID) to select * @return APDU for SELECT Aid Command */public static byte[] BUILDSELECTAPDU (String aid) {//Format: [CLASS | instruction | PARAMETER 1 | PARAMETER 2 | LENGTH | DATA] Return Hexstringtobytearray (Select_apdu_header + String.Format ("%02 x ", Aid.length ()/2) + aid);     }/** * Utility class to convert a byte array to a hexadecimal string.     * * @param bytes bytes to convert * @return String, containing hexadecimal representation. */public static String bytearraytohexstring (byte[] bytes) {final char[] Hexarray = {' 0 ', ' 1 ', ' 2 ', ' 3 ', ' 4 ', ' 5 ', ' 6        ', ' 7 ', ' 8 ', ' 9 ', ' A ', ' B ', ' C ', ' D ', ' E ', ' F '};        char[] Hexchars = new char[bytes.length * 2];        int V;            for (int j = 0; J < Bytes.length; J + +) {v = bytes[j] & 0xFF;            HEXCHARS[J * 2] = Hexarray[v >>> 4];        HEXCHARS[J * 2 + 1] = hexarray[v & 0x0F];    } return new String (Hexchars);     }/** * Utility class to convert a hexadecimal string to a byte string.     * * <p>behavior with input strings containing non-hexadecimal characters are undefined.   * * @param s String containing hexadecimal characters to convert * @return Byte array generated from input  */public static byte[] Hexstringtobytearray (String s) {int len = s.length ();        byte[] data = new BYTE[LEN/2];                    for (int i = 0; i < len; i + = 2) {DATA[I/2] = (byte) ((Character.digit (S.charat (i), +) << 4)        + Character.digit (S.charat (i+1), 16));    } return data; }}



Mobile payment Smart IC card for NFC communication with Android phone

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.