package com.dayu.recharge.tools; import android.content.Intent; import android.nfc.NfcAdapter; import android.nfc.Tag; import android.nfc.tech.MifareClassic; import android.util.Base64; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; /** * @author zx * @date 2018/4/25 8:08 * email 1058083107@qq.com * description */ public class NFCWriteHelper extends BaseNFCHelper{ private Tag tag; private NFCWriteHelper.NFCCallback callback; private static NFCWriteHelper helper; private static int PASSWORD_LENTH = 6; public NFCWriteHelper(Intent intent) { this.tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); } /** * 单例初始化 * * @param intent * @return */ public static NFCWriteHelper getInstence(Intent intent) { if (helper == null) { helper = new NFCWriteHelper(intent); } return helper; } /** * 设置NFC卡的读取密码 * * @param str * @return */ public NFCWriteHelper setReadPassword(String str) { if (null != str && (str.length() <= PASSWORD_LENTH)) { for (int i = 0; i < str.length(); i++) { bytes[i] = (byte) str.charAt(i); } } return helper; } /** * 写卡 * * @param str 书写内容,16个字节 * @param a 书写的扇区 (从0开始数) * @param b 书写的块(从0开始数) * @param callback 返回监听 */ public void writeData(byte[] str, int a, int b, NFCWriteHelper.NFCCallback callback) { if (str.length <= 16) { try { MifareClassic mfc = MifareClassic.get(tag); if (null != mfc) { try { //连接NFC mfc.connect(); //获取扇区数量 int count = mfc.getSectorCount(); //如果传进来的扇区大了或者小了直接退出方法 if (a > count - 1 || a < 0) { callback.isSusses(false); return; } //获取写的扇区的块的数量 int bCount = mfc.getBlockCountInSector(a); //如果输入的块大了或者小了也是直接退出 if (b > bCount - 1 || b < 0) { callback.isSusses(false); return; } //验证扇区密码 boolean isOpen = mfc.authenticateSectorWithKeyA(a, bytes); if (isOpen) { int bIndex = mfc.sectorToBlock(a); //写卡 mfc.writeBlock(bIndex + b, str); callback.isSusses(true); return; } callback.isSusses(false); } catch (Exception e) { e.printStackTrace(); callback.isSusses(false); } finally { try { mfc.close(); } catch (IOException e) { e.printStackTrace(); } } } } catch (Exception e) { e.printStackTrace(); } } } /** * 修改密码 * * @param password 书写密码,16个字节 * @param a 书写的扇区 * @param callback 返回监听 */ public void changePasword(String password, int a, final NFCWriteHelper.NFCCallback callback) { MifareClassic mfc = MifareClassic.get(tag); byte[] data = new byte[16]; if (null != mfc) { try { mfc.connect(); if (password.length() != PASSWORD_LENTH) { callback.isSusses(false); return; } int count = mfc.getSectorCount(); if (a > count - 1 || a < 0) { callback.isSusses(false); return; } //将密码转换为keyA for (int i = 0; i < password.length(); i++) { data[i] = (byte) password.charAt(i); } //将密码转换为KeyB for (int i = 0; i < password.length(); i++) { data[i + password.length() + 4] = (byte) password.charAt(i); } //输入控制位 data[password.length()] = (byte) 0xff; data[password.length() + 1] = (byte) 0x07; data[password.length() + 2] = (byte) 0x80; data[password.length() + 3] = (byte) 0x69; //验证密码 boolean isOpen = mfc.authenticateSectorWithKeyA(a, bytes); if (isOpen) { int bIndex = mfc.sectorToBlock(a); int bCount = mfc.getBlockCountInSector(a); //写到扇区的最后一个块 mfc.writeBlock(bIndex + bCount - 1, data); } callback.isSusses(true); } catch (Exception e) { e.printStackTrace(); callback.isSusses(false); } finally { try { mfc.close(); } catch (IOException e) { e.printStackTrace(); } } } } /** * 返回监听类 */ public interface NFCCallback { /** * 返回是否成功 * * @param flag */ void isSusses(boolean flag); } }