private void setupForegroundDispatch() { try { IntentFilter filter = new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED); filter.addDataType(MIME_TEXT_PLAIN); mIntentFilters = new IntentFilter[] { filter, }; mTechLists = new String[][] { new String[] { MifareClassic.class.getName() } }; mPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0); } catch(IntentFilter.MalformedMimeTypeException e) { Log.e(LOG_TAG, "Malformed mime type"); } }
private void authenticateA(int sector, byte[] key) throws Exception { if (mTag.authenticateSectorWithKeyA(sector, key)) { return; } // if (mTag.authenticateSectorWithKeyB(sector, // MifareClassic.KEY_DEFAULT)) { // publishProgress("authenticated with default key"); // return; // } if (mTag.authenticateSectorWithKeyA(sector, MifareClassic.KEY_DEFAULT)) { return; } byte[] inverted = new byte[key.length]; for (int i = 0; i < key.length; ++i) inverted[i] = (byte) ~key[i]; if (mTag.authenticateSectorWithKeyA(sector, inverted)) { log("authenticated with inverted sector key"); return; } throw new Exception("Authentication error"); }
private void authenticateB(int sector, byte[] key) throws Exception { if (mTag.authenticateSectorWithKeyB(sector, key)) { return; } if (mTag.authenticateSectorWithKeyB(sector, MifareClassic.KEY_DEFAULT)) { log("authenticated with default key"); return; } byte[] inverted = new byte[key.length]; for (int i = 0; i < key.length; ++i) inverted[i] = (byte) ~key[i]; if (mTag.authenticateSectorWithKeyB(sector, inverted)) { log("authenticated with inverted sector key"); return; } throw new Exception("Authentication error"); }
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_launcher); pendingIntent = PendingIntent.getActivity(this, 0, new Intent("de.Ox539.kitcard.reader.TECH_DISCOVERED").addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0); final IntentFilter intentFilter = new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED); intentFiltersArray = new IntentFilter[] { intentFilter }; techListsArray = new String[][] { new String[] { MifareClassic.class.getName() } }; NfcManager manager = (NfcManager) getSystemService(Context.NFC_SERVICE); adapter = manager.getDefaultAdapter(); if (!adapter.isEnabled()) { Toast.makeText(getApplicationContext(), getResources().getString(R.string.activate_nfc), Toast.LENGTH_LONG).show(); startActivity(new Intent(android.provider.Settings.ACTION_WIRELESS_SETTINGS)); } }
protected Pair<ReadCardResult, Wallet> doInBackground(Tag... tags) { MifareClassic card = null; try { card = MifareClassic.get(tags[0]); } catch (NullPointerException e) { /* Error while reading card. This problem occurs on HTC devices from the ONE series with Android Lollipop (status of June 2015) * Try to repair the tag. */ card = MifareClassic.get(MifareUtils.repairTag(tags[0])); } if(card == null) return new Pair<ReadCardResult, Wallet>(null, null); final Wallet wallet = new Wallet(card); final ReadCardResult result = wallet.readCard(); return new Pair<ReadCardResult, Wallet>(result, wallet); }
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); euroFormat = new EuroFormat(); pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0); final IntentFilter intentFilter = new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED); intentFiltersArray = new IntentFilter[] { intentFilter }; techListsArray = new String[][] { new String[] { MifareClassic.class.getName() } }; setContentView(R.layout.activity_scan); resolveIntent(getIntent()); setTitle(getResources().getString(R.string.app_name)); NfcManager manager = (NfcManager) getSystemService(Context.NFC_SERVICE); adapter = manager.getDefaultAdapter(); if (!adapter.isEnabled()) { Toast.makeText(getApplicationContext(), getResources().getString(R.string.activate_nfc), Toast.LENGTH_LONG).show(); startActivity(new Intent(android.provider.Settings.ACTION_WIRELESS_SETTINGS)); } }
void resolveIntent(Intent intent) { // 1) Parse the intent and get the action that triggered this intent String action = intent.getAction(); // 2) Check if it was triggered by a tag discovered interruption. if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)) { // 3) Get an instance of the TAG from the NfcAdapter Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); // 4) Get an instance of the Mifare classic card from this TAG // intent MifareClassic mfc = MifareClassic.get(tagFromIntent); try { mfc.connect(); mRKFCard = new RKFCard(mfc); mCardContents = mRKFCard.readEntireCard(); txtRaw.setText(DataType.getHexString(mCardContents)); } catch (IOException e1) { Log.e(TAG, e1.getLocalizedMessage(), e1); } Toast t = Toast.makeText(this, "Dump done!", Toast.LENGTH_SHORT); t.show(); } }
@Override public void onResume() { super.onResume(); if(oldIntent != getIntent()) { if(NfcAdapter.ACTION_TECH_DISCOVERED.equals(getIntent().getAction())) { Tag tag = getIntent().getParcelableExtra(NfcAdapter.EXTRA_TAG); mfc = null; if(tag != null) { mfc = MifareClassic.get(tag); } debugString = ""; if(null != mfc) { readCard(); } } } oldIntent = getIntent(); }
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.nfc); mAdapter = NfcAdapter.getDefaultAdapter(this); if (mAdapter == null) { this.finish(); return; } mPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0); IntentFilter filter = new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED); try { filter.addDataType("*/*"); } catch (IntentFilter.MalformedMimeTypeException e) { e.printStackTrace(); } mIntentFilters = new IntentFilter[]{filter}; mTechList = new String[][]{new String[]{MifareClassic.class.getName()}}; initViews(); }
private void tagDetected(Tag tag) { MifareClassic mifareTag = MifareClassic.get(tag); if (mifareTag == null) { Toast.makeText(this, getString(R.string.err_unknown_card_type), Toast.LENGTH_SHORT).show(); return; } if (!mState.hasKeys()) { Toast.makeText(this, R.string.tag_no_keys, Toast.LENGTH_SHORT).show(); } else if (mState.getState() == DomainState.State.CLEAN) { Toast.makeText(this, R.string.tag_not_recording, Toast.LENGTH_SHORT).show(); } else if (mState.getState() == DomainState.State.LOADED) { Toast.makeText(this, R.string.tag_not_replaying, Toast.LENGTH_SHORT).show(); } else if (mState.getState() == DomainState.State.RECORDING) { readTag(mifareTag); } else if (mState.getState() == DomainState.State.REPLAYING) { writeTag(mifareTag); } }
public void writeTag(MifareClassic tag) { // Test key compatibility if (tag.getSectorCount() > mState.getKeys().getSectorCount()) { Toast.makeText(this, R.string.err_to_few_keys, Toast.LENGTH_SHORT).show(); return; } // Get UID from tag and cmp with byte[] newUID = tag.getTag().getId(); byte[] recordedUID = mState.getTag().getUID(); for (int i = 0; i < recordedUID.length; i++) { if (newUID[i] != recordedUID[i]) { Toast.makeText(this, R.string.err_wrong_uid, Toast.LENGTH_SHORT).show(); return; } } // Create a retaining fragment and start the task TaskFragment taskFragment = new TaskFragment(); WriteMifareTask writeTask = new WriteMifareTask(mState, taskFragment); taskFragment.initialize(mState, writeTask, getString(R.string.write_tag_progress)); taskFragment.show(mFragmentManager, TASK_FRAGMENT_TAG); writeTask.execute(tag); }
/** * Must not refer to the activity from this or the processMifareTag * override. */ @Override protected Result doInBackground(MifareClassic... tagParam) { if (tagParam == null || tagParam.length != 1 || tagParam[0].getType() != MifareClassic.TYPE_CLASSIC) { mError = new Exception("Invalid tag type"); return null; } MifareClassic tag = tagParam[0]; try { // Use publishProgress(0 .. 100) from the prcessMifareTag function return processMifareTag(tag); } catch (IOException e) { mError = e; return null; } }
@Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); mNfcAdapter = NfcAdapter.getDefaultAdapter(getActivity()); Intent intent = new Intent(getActivity(), getActivity().getClass()); intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); mPendingIntent = PendingIntent.getActivity(getActivity(), 0, intent, 0); mTechLists = new String[][] {new String[] {MifareClassic.class.getName()}}; IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED); try { ndef.addDataType("*/*"); } catch (MalformedMimeTypeException e) { throw new RuntimeException("fail", e); } mFilters = new IntentFilter[] {ndef}; setButtonVisibility(true); }
protected Void doInBackground(Void... v) { if (mTag.getType() != MifareClassic.TYPE_CLASSIC || mTag.getSize() != MifareClassic.SIZE_1K) { log("Invalid card type, only supporting Mifare Classic 1k"); return null; } log("Preparing tag..."); resetKeys(); mRunning = true; for (int i = 0; i < nRuns; ++i) { if (isCancelled()) break; runSingle(i); } try { mTestLog.writeToFile("/storage/sdcard0/mifare_test.log"); } catch (IOException e) { log("Error writing to log file"); } log("Restoring default keys"); resetKeys(); mRunning = false; return null; }
@Override protected void onResume() { super.onResume(); NfcManager nMan = (NfcManager) this .getSystemService(Context.NFC_SERVICE); mNfcAdapter = nMan.getDefaultAdapter(); PendingIntent pi = createPendingResult(PENDING_INTENT_TECH_DISCOVERED, new Intent(), 0); mNfcAdapter .enableForegroundDispatch( this, pi, new IntentFilter[] { new IntentFilter( NfcAdapter.ACTION_TECH_DISCOVERED) }, new String[][] { new String[] { android.nfc.tech.MifareClassic.class .getName() }, new String[] { android.nfc.tech.IsoDep.class .getName() } }); if (mTerminal == null) { mTerminal = // new OpenMobileAPITerminal(this, this); NfcTerminal.getInstance(this); } mTCPConnection = new TCPConnection(this, this); Thread td = new Thread(mTCPConnection); td.start(); }
public MifareMad(MifareClassic card) throws IOException { this.card = card; if(!card.isConnected()) { try { card.connect(); readMad(); } finally { card.close(); } } else { readMad(); } }
private boolean readMad() throws IOException { if(!card.authenticateSectorWithKeyA(0, MifareClassic.KEY_MIFARE_APPLICATION_DIRECTORY)) { Log.e("KITCard Reader", "Authentication with sector 0 failed"); return false; } byte[] mad_descriptor = card.readBlock(card.sectorToBlock(0) + 3); byte general_purpose_byte = mad_descriptor[9]; mad_version = general_purpose_byte & 3; multi_app = (general_purpose_byte & (1 << 7)) != 0; mad_available = (general_purpose_byte & (1 << 6)) != 0; publisher_sector = 0; if (mad_available) { byte[] mad = new byte[16*2]; byte[] data = card.readBlock(card.sectorToBlock(0) + 1); System.arraycopy(data, 0, mad, 0, 16); data = card.readBlock(card.sectorToBlock(0) + 2); System.arraycopy(data, 0, mad, 16, 16); publisher_sector = mad[1] & 0x3f; for(int a = 2; a < mad.length; a += 2) { app_list.add(new MifareApp(mad[a], mad[a + 1])); } } return true; }
private void readBlocks(MifareClassic mfc, int sectorIndex) throws IOException { int startBlockIndex = mfc.sectorToBlock(sectorIndex); for(int block = startBlockIndex; block < (startBlockIndex + 3); block++){ final byte[] data = mfc.readBlock(block); mCard.addBlock(sectorIndex, (block%4), data); } }
private int randomBlockIndex(MifareClassic mfc) { int i = new Random().nextInt(mfc.getBlockCount()); if (i == 0 || (i + 1) % 4 == 0) { return randomBlockIndex(mfc); } return i; }
private void initializeNFC() { mNfcAdapter = NfcAdapter.getDefaultAdapter(this); mPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0); mFilters = new IntentFilter[] { new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED) }; mTechLists = new String[][] { new String[] { MifareClassic.class.getName() } }; }
public void readTag(MifareClassic tag) { // Test key compatibility if (tag.getSectorCount() > mState.getKeys().getSectorCount()) { Toast.makeText(this, R.string.err_to_few_keys, Toast.LENGTH_SHORT).show(); return; } // Create a retaining fragment and start the task TaskFragment taskFragment = new TaskFragment(); ReadMifareTask readTask = new ReadMifareTask(mState, taskFragment); taskFragment.initialize(mState, readTask, getString(R.string.read_tag_progress)); taskFragment.show(mFragmentManager, TASK_FRAGMENT_TAG); readTask.execute(tag); }
public MifareTest(MifareClassic tag, Context context, LogMe log) { mTag = tag; mContext = (MainActivity) context; mLog = log; mTestLog = new Log(); }
private void writeMifareClassic(final Intent intent) { new AsyncTask<Void, Void, Object[]>() { @Override protected void onPreExecute() { setProgressBarIndeterminateVisibility(true); App.utils.toggleButtons(false); App.mAdapter = NfcAdapter.getDefaultAdapter(App.context); App.mPendingIntent = PendingIntent.getActivity(App.context, 0, new Intent(App.context, getClass()) .addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0); } @Override protected Object[] doInBackground(Void... arg0) { Log.d(App.TAG, "intent.getAction() -> " + intent.getAction()); if (NfcAdapter.ACTION_TECH_DISCOVERED .equals(intent.getAction())) { App.mTagFromIntent = intent .getParcelableExtra(NfcAdapter.EXTRA_TAG); App.mClassic = MifareClassic.get(App.mTagFromIntent); writeMifareSectors(); } else { infoTextUpdate("[●] Tag to write not found. \n"); } return null; } @Override protected void onPostExecute(Object[] data) { setProgressBarIndeterminateVisibility(false); App.utils.toggleButtons(true); App.mAdapter = null; App.mPendingIntent = null; } }.execute(); }
private void readMifareClassic(final Intent intent) { new AsyncTask<Void, Void, Object[]>() { @Override protected void onPreExecute() { setProgressBarIndeterminateVisibility(true); App.utils.toggleButtons(false); App.mAdapter = NfcAdapter.getDefaultAdapter(App.context); App.mPendingIntent = PendingIntent.getActivity(App.context, 0, new Intent(App.context, getClass()) .addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0); } @Override protected Object[] doInBackground(Void... arg0) { Log.d(App.TAG, "intent.getAction() -> " + intent.getAction()); if (NfcAdapter.ACTION_TECH_DISCOVERED .equals(intent.getAction())) { App.mTagFromIntent = intent .getParcelableExtra(NfcAdapter.EXTRA_TAG); if (isTechPresent(App.mTagFromIntent.getTechList(), MifareClassic.class.getName())) { App.mClassic = MifareClassic.get(App.mTagFromIntent); readMifareClassicSectors(); } } else { infoTextUpdate("[●] ReadTag :: Mifare Classic not found. \n"); } return null; } @Override protected void onPostExecute(Object[] data) { setProgressBarIndeterminateVisibility(false); App.utils.toggleButtons(true); App.mAdapter = null; App.mPendingIntent = null; } }.execute(); }
private void write(MifareClassic tag, byte[] payload) { // TODO implement }
public Wallet(MifareClassic card) { this.card = card; }
/** * Repairs the broken tag on HTC devices running Android 5.x * <p/> * "It seems, the reason of this bug in TechExtras of NfcA is null. However, TechList contains MifareClassic." -bildin * For more information please refer to https://github.com/ikarus23/MifareClassicTool/issues/52#issuecomment-103797115 * <p/> * Code source: https://github.com/ikarus23/MifareClassicTool/issues/52#issuecomment-104277445 * * @param oTag The broken tag * @return The fixed tag */ public static Tag repairTag(Tag oTag) { if (oTag == null) return null; String[] sTechList = oTag.getTechList(); Parcel oParcel, nParcel; oParcel = Parcel.obtain(); oTag.writeToParcel(oParcel, 0); oParcel.setDataPosition(0); int len = oParcel.readInt(); byte[] id = null; if (len >= 0) { id = new byte[len]; oParcel.readByteArray(id); } int[] oTechList = new int[oParcel.readInt()]; oParcel.readIntArray(oTechList); Bundle[] oTechExtras = oParcel.createTypedArray(Bundle.CREATOR); int serviceHandle = oParcel.readInt(); int isMock = oParcel.readInt(); IBinder tagService; if (isMock == 0) { tagService = oParcel.readStrongBinder(); } else { tagService = null; } oParcel.recycle(); int nfca_idx = -1; int mc_idx = -1; for (int idx = 0; idx < sTechList.length; idx++) { if (sTechList[idx].equals(NfcA.class.getName())) { nfca_idx = idx; } else if (sTechList[idx].equals(MifareClassic.class.getName())) { mc_idx = idx; } } if (nfca_idx >= 0 && mc_idx >= 0 && oTechExtras[mc_idx] == null) { oTechExtras[mc_idx] = oTechExtras[nfca_idx]; } else { return oTag; } nParcel = Parcel.obtain(); nParcel.writeInt(id.length); nParcel.writeByteArray(id); nParcel.writeInt(oTechList.length); nParcel.writeIntArray(oTechList); nParcel.writeTypedArray(oTechExtras, 0); nParcel.writeInt(serviceHandle); nParcel.writeInt(isMock); if (isMock == 0) { nParcel.writeStrongBinder(tagService); } nParcel.setDataPosition(0); Tag nTag = Tag.CREATOR.createFromParcel(nParcel); nParcel.recycle(); return nTag; }
public RKFCard(MifareClassic mfc) throws IOException { mMFC = mfc; parse(); }
private byte[] readBlock(MifareClassic mfc, int blockIndex) throws IOException { return mfc.readBlock(blockIndex); }
private void writeBlock(MifareClassic mfc, int blockIndex, byte[] data) throws IOException { mfc.writeBlock(blockIndex, data); }
private boolean validateBlockIndex(MifareClassic mfc, int blockIndex) { if (blockIndex >= mfc.getBlockCount()) { return false; } return true; }
@Override protected Tag processMifareTag(MifareClassic mfTag) throws IOException { MifareIO mio = new MifareIO(mfTag, getDomainState().getKeys(), this); return mio.read(); }
@Override protected Void processMifareTag(MifareClassic mfTag) throws IOException { MifareIO mio = new MifareIO(mfTag, getDomainState().getKeys(), this); mio.write(getDomainState().getTag()); return null; // Void return }
private void runMifareTest(Tag tag) { MifareClassic mf = MifareClassic.get(tag); mMifareTest = new MifareTest(mf, this, MAIN_Log); mMifareTest.execute(); dismissDialog(DIALOG_MF_WAIT_FOR_TAG); showDialog(DIALOG_MF_WAIT_FOR_FINISH); }
/** * Create an instance of the helper class to interface a tag using some * keys. * * @param tag * The Mifare tag to interface * @param keys * The keys to use in communication. */ public MifareIO(MifareClassic tag, KeyChain keys, IProgressListener progressListener) { assert (tag != null && keys != null); mTag = tag; mKeys = keys; mProgressListener = progressListener; }
/** * Must not modify the domain state in this method. */ protected abstract Result processMifareTag(MifareClassic mfTag) throws IOException;