acr1252 + Android HCE (host card emulator emulate) physical card

I try to emulate emv card on Android device. And it will be read on acr1252 over some software. It's work fine, software can read card but identifies like token, but in emv answer I set it like physical card.

AndroidManifest.xml

    <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.ptks.cardEmulator">

    <uses-permission android:name="android.permission.ACCESS_SUPERUSER" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-feature android:name="android.hardware.nfc.hce" android:required="true" />
    <uses-permission android:name="android.permission.NFC" />
    <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
    <uses-feature android:name="android.hardware.nfc" android:required="false" />



    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.Android_CardEmulator"
        tools:targetApi="31">
        <activity
            android:name=".MainActivity"
            android:exported="true"
            android:directBootAware="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

            <intent-filter>
                <category android:name="android.intent.category.LAUNCHER" />
                <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
                <action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" />
            </intent-filter>
            <meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" android:resource="@xml/usb_device_filter" />

        </activity>



        <service
            android:name=".MyHostApduService"
            android:exported="true"
            android:permission="android.permission.BIND_NFC_SERVICE">
            <intent-filter>
                <action android:name="android.nfc.cardemulation.action.HOST_APDU_SERVICE" />
                <category android:name="android.intent.category.DEFAULT"/>
            </intent-filter>
            <meta-data
                android:name="android.nfc.cardemulation.host_apdu_service"
                android:resource="@xml/apduservice" />

        </service>


        <service
            android:name=".UsbService"
            android:enabled="true">
        </service>


    </application>

</manifest>

apduservice.xml

<?xml version="1.0" encoding="utf-8"?>
<host-apdu-service xmlns:android="http://schemas.android.com/apk/res/android"
    android:description="@string/service_description"
    android:requireDeviceUnlock="false">
    <aid-group
        android:description="@string/aid_group_description"
        android:category="payment">
        <aid-filter android:name="A0000000041010" />
        <aid-filter android:name="A0000000031010" />
    </aid-group>
</host-apdu-service>

Please, help, how to correct sent that I "use" physical card? Thanks!

P.S. HostApduService:

    package com.cardEmulator;

import static com.cardEmulator.MainActivity.changeNfcEnabled;

import android.nfc.cardemulation.HostApduService;
import android.os.Bundle;
import android.util.Log;

public class MyHostApduService extends HostApduService {

    private byte[] hexToBinary(String s) {


        byte[] data = new byte[s.length()/2];

        for( int i=0, j=0;
             i<s.length() && j<data.length;
             i+=2, j++)
        {


            if ((byte)Integer.parseInt(s.substring(i, i+2), 16) >=0 && (byte)Integer.parseInt(s.substring(i, i+2), 16)<16)
                data[j] = (byte) (0 + (byte)Integer.parseInt(s.substring(i, i+2), 16));
            else
                data[j] = (byte)Integer.parseInt(s.substring(i, i+2), 16);
        }

        return data;
    }


    @Override
    public byte[] processCommandApdu(byte[] commandApdu, Bundle extras) {

        Log.d("chrome", "Get command from card: ");



        String getReq = "";

        for (int i = 0; i<=commandApdu.length-1; i++)
            getReq+=String.format("%02x", commandApdu [i]);


            Log.d("chrome", getReq);

if (getReq.toLowerCase().contains("00A4040007A00000000".toLowerCase())) {
  
    Log.d("chrome", "Send first answer");

    sendResponseApdu(hexToBinary("6F23840E325041592E5359532E4444463031A511BF0C0E610C4F07A00000000410108701019000"));
}


if (getReq.toLowerCase().contains("80a8000002830000".toLowerCase())) {
    sendResponseApdu(hexToBinary("771282021980940C0000000000000000000000009000"));
  
}
        Globals.curCard = "5167803202840547";

        if (getReq.toLowerCase().contains("00b2000400".toLowerCase()))
            sendResponseApdu(hexToBinary("7081A657135167803202840547D24112010000000001960F5A0851678032028405475F24032411305F25031911015F280208045F3401018C279F02069F03069F1A0295055F2A029A039C019F37049F35019F45029F4C089F34039F21039F7C148D0C910A8A0295059F37049F4C088E0E000000000000000042031E031F039F0702FFC09F080200029F0D05B4508400009F0E0500000000009F0F05B4708480009F420209809F4A01829000"));


        if (getReq.toLowerCase().contains("00b2011400".toLowerCase()))
            sendResponseApdu(hexToBinary("7081A657135167803202840547D24112010000000001960F5A0851678032028405475F24032411305F25031911015F280208045F3401018C279F02069F03069F1A0295055F2A029A039C019F37049F35019F45029F4C089F34039F21039F7C148D0C910A8A0295059F37049F4C088E0E000000000000000042031E031F039F0702FFC09F080200029F0D05B4508400009F0E0500000000009F0F05B4708480009F420209809F4A01829000"));
       

if (getReq.toLowerCase().equals("80ca9f7f00".toLowerCase()))

           sendResponseApdu(hexToBinary( "9F7F08425032729000" ));

        return null;
    }

    @Override
    public void onDeactivated(int reason) {

        Log.d("chrome", "Communication with the card reader is interrupted!!!");

    }
}

Upvotes: 0

Views: 153

Answers (0)

Related Questions