“获取处理选项”总是6700(错误的Lc或Le)

时间:2013-12-27 20:34:46

标签: android nfc smartcard apdu emv

我正试图通过我的LG P710 Optimus L7 2读取智能卡 我正在关注此tutorial

我可以选择“1PAY.SYS.DDF01”目录
我可以选择应用程序

但我无法执行“获取处理选项” 它总是导致6700错误(Lc或Le错误)

这是我的代码

NfcAdapter mNFCAdapter;
Intent intent;
PendingIntent pendingIntent;
private TextView mTextView;
String[][] techList;
IntentFilter[] filters = new IntentFilter[3];

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    mTextView = (TextView) findViewById(R.id.title);

    mNFCAdapter = NfcAdapter.getDefaultAdapter(this);

    intent = new Intent(getApplicationContext(), getClass());
    intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

    pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent, 0);


    techList = new String[][]{
            new String[]
                    { MifareClassic.class.getName() },
            new String[]
                    { IsoDep.class.getName() }
            };

    filters[0] = new IntentFilter();
    filters[0].addAction(NfcAdapter.ACTION_NDEF_DISCOVERED);
    filters[0].addCategory(Intent.CATEGORY_DEFAULT);
    // add type of tag data you want to have - here ndef -> plain text
    try {
        filters[0].addDataType(MIME_TEXT_PLAIN);
    } catch (MalformedMimeTypeException e) {
        e.printStackTrace();
    }

    filters[1] = new IntentFilter();
    filters[1].addAction(NfcAdapter.ACTION_TAG_DISCOVERED);
    filters[1].addCategory(Intent.CATEGORY_DEFAULT);

    filters[2] = new IntentFilter();
    filters[2].addAction(NfcAdapter.ACTION_TECH_DISCOVERED);
    filters[2].addCategory(Intent.CATEGORY_DEFAULT);

}

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    String action = intent.getAction();
    mTextView.setText(action);
    Toast.makeText(getApplicationContext(), action, Toast.LENGTH_SHORT).show();

    Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
    IsoDep tagIsoDep;

    if((tagIsoDep = IsoDep.get(tagFromIntent)) != null)
        if(handleIsoDep(tagIsoDep))
            return;

}
     private boolean handleIsoDep(IsoDep tag){
    try{ 
        tag.connect(); 
        tag.setTimeout(20); 
        byte[] responseAPDU;


        //2PAY.SYS.DDF01
        byte[] select_Dir = new byte[]{ 
                (byte)0x00, (byte)0xa4, (byte)0x04, (byte)0x00, (byte)0x0e,
                (byte)0x32, (byte)0x50, (byte)0x41, (byte)0x59, (byte)0x2e,
                (byte)0x53, (byte)0x59, (byte)0x53, (byte)0x2e, (byte)0x44, 
                (byte)0x44, (byte)0x46, (byte)0x30, (byte)0x31
        };

        //Select CC Applet
        byte[] select_Applet = new byte[]{ 
                (byte)0x00, (byte)0xa4, (byte)0x04, (byte)0x00, (byte)7, 
                (byte)0xa0, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x04,
                (byte)0x30, (byte)0x60
        };

        //Send GET PROCESSING OPTIONS command
        byte[] Send_Get = new byte[]{ 
                (byte)0x80,(byte)0xA8,(byte)0x00,(byte)0x00,(byte)0x02,
                (byte)0x83,(byte)0x00,
                (byte)0x00
        };


        responseAPDU = tag.transceive(select_Dir); 
        mTextView.setText(mTextView.getText() + handleResponse(responseAPDU));

这将返回APDU-Statusword 9000 - >成功

        responseAPDU = tag.transceive(select_Applet); 
        mTextView.setText(mTextView.getText() + handleResponse(responseAPDU));

这将返回APDU-Statusword 9000 - >成功

        responseAPDU = tag.transceive(Send_Get); 
        mTextView.setText(mTextView.getText() + handleResponse(responseAPDU));

这个问题出现了:它返回6700 - >错误的Lc或Le

        mTextView.setText(mTextView.getText() + "\n\nDone");
        tag.close();

     } catch (IOException e) {
            e.printStackTrace();
            return false;
    }
    return true;
}

函数handleResponse只是将“responseAPDU”从Binary解析为Hex,突出显示Statusword

有人可以告诉我出了什么问题吗? 或者只是帮助我?

PS sry for bad english;)


作为对我的应用程序的回应 - 选择我得到:

6f298407a0000000043060a51e50074d41455354524f5f2d046465656e9f38039f5c08bf0c059f4d020b0a9000

6F -> FCI Template 29  
84 -> DF Name 07 A0 00 00 00 04 30 60  
A5 -> FCI Properietary Template 1E  
50 -> Application Lable 07 4D 41 45 53 54 52 4F 5F 2D 04 64 65 6E  
9F38 -> PDOL 03 9F 5C 08  
BF0C -> FCI Issuer Data 05  
9F4D -> Log Entry 02 0B  
0A Additional Issuer Data

但我不知道从GET处理选项中插入数据文件的内容是什么 请参阅EMV第3册“5.4使用数据对象列表规则(DOL)”一节中的指南。
所以我只需要设置数据字段83 03 9F 5C 08
并且Lc = 5?

1 个答案:

答案 0 :(得分:8)

为了帮助您,需要整个ADPU对话框(命令/响应)。

但是,根据您的代码:硬编码您的select_Dir和select_Applet命令是正确的,但您不能硬编码GET PROCESSING OPTIONS命令,其语法取决于卡(ICC)的响应你的select_Applet命令。

EMV 4.3 Book 1“表45:ADF的SELECT响应消息数据字段(FCI)”,解释了对SELECT命令的成功卡响应包含“处理选项数据对象”列表“(PDOL,标签9F38)。这是卡片处理交易所需的字段列表(例如:金额,......)。这些字段值将由终端(您的电话)通过GET PROCESSING OPTIONS命令数据字段(标记83)返回到卡中,如EMV 4.3 book 3中记录的那样,“6.5.8.3数据字段已发送在命令消息“

  

命令消息的数据字段是根据ICC提供的PDOL 编码的数据对象,如5.4节所定义,并由标记'83'引入。当ICC未提供数据对象列表时,终端将模板的长度字段设置为零。否则,模板的长度字段是传输到ICC的数据对象的值字段的总长度。

知道:

  • 您选择的AID(A0 00 00 00 04 30 60)是Mastercard Maestro,不太可能有空的PDOL
  • 但您的GET PROCESSING OPTIONS命令未在其数据字段中列出任何值
  • 您的GET PROCESSING OPTIONS数据字段的长度与PDOL中卡所请求字段的总长度之间可能不匹配,因此卡返回6700检查错误(EMV Book 1, “表33:获取响应错误条件”)。

您已将卡请求的PDOL识别为:9F38 - > 03 9F 5C 08。 03告诉你PDOL长3个字节。 9F5C是请求字段的标记,08是电话返回的字段值的长度。

标签9F5C在EMV非接触式2.3 Book C2 kernel 2 specification中定义,部分“A.1.59 DS请求的操作员ID”。 DS请求的运营商ID定义为

  

包含终端确定的数据运营商标识符   存储。它将被发送到GET PROCESSING中的卡片   选项命令。

我不熟悉这个标签,所以我不能告诉你什么是合适的价值。 但是,这里是GET PROCESSING OPTIONS命令的数据字段应该是什么样的,假设DS请求的操作员ID具有值01 02 03 04 05 06 07 08,并且在EMV Book 3中给出了数据对象列表格式化指南, “5.4使用数据对象列表(DOL)的规则”部分:

  

83 08 01 02 03 04 05 06 07 08

且Lc = 10