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 android.util.Log; 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 static NFCWriteHelper helper; private static int PASSWORD_LENTH = 12; 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++) { defauleKey[i] = (byte) str.charAt(i); } } return helper; } /** * 写卡 * * @param str 书写内容,16个字节 * @param a 书写的扇区 (从0开始数) * @param b 书写的块(从0开始数) * @param */ public boolean writeData(byte[] str, int a, int b) { Log.i("NFCWreatActivity", "writeData: a=" + a + " b=" + b); //写卡时修改所有密码 changePasword(a); 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) { return false; } //获取写的扇区的块的数量 int bCount = mfc.getBlockCountInSector(a); //如果输入的块大了或者小了也是直接退出 if (b > bCount - 1 || b < 0) { return false; } //验证扇区密码 boolean isOpen = mfc.authenticateSectorWithKeyA(a, defauleKey); if (!isOpen) { isOpen = mfc.authenticateSectorWithKeyA(a, companyKey); } if (isOpen) { int bIndex = mfc.sectorToBlock(a); //写卡 mfc.writeBlock(bIndex + b, str); return true; } return false; } catch (Exception e) { e.printStackTrace(); return false; } finally { try { mfc.close(); } catch (IOException e) { e.printStackTrace(); } } } } catch (Exception e) { e.printStackTrace(); return false; } } return false; } /** * 修改密码 * * @param a 书写的扇区 * // * @param callback 返回监听 */ public boolean changePasword(int a) { MifareClassic mfc = MifareClassic.get(tag); byte[] data = new byte[16]; if (null != mfc) { try { mfc.connect(); int count = mfc.getSectorCount(); boolean isOpen = mfc.authenticateSectorWithKeyA(a, defauleKey); //验证是否是默认密码,当默认密码时修改密码 if (isOpen) { //将密码转换为keyA byte[] dataA = HexUtil.hexToByteArray(companyKeyA); for (int i = 0; i < dataA.length; i++) { data[i] = dataA[i]; } //输入控制位 data[6] = (byte) 0xff; data[7] = (byte) 0x07; data[8] = (byte) 0x80; data[9] = (byte) 0x69; byte[] dataB = HexUtil.hexToByteArray(companyKeyB); //将密码转换为KeyB for (int i = 0; i < dataB.length; i++) { data[i + 10] = dataB[i]; } int bIndex = mfc.sectorToBlock(a); int bCount = mfc.getBlockCountInSector(a); //写到扇区的最后一个块 mfc.writeBlock(bIndex + bCount - 1, data); } return true; } catch (Exception e) { e.printStackTrace(); return false; // callback.isSusses(false); } finally { try { mfc.close(); } catch (IOException e) { e.printStackTrace(); } } } return false; } /** * 返回监听类 */ public interface NFCCallback { /** * 返回是否成功 * * @param flag */ void isSusses(boolean flag); } }