左晓为主开发手持机充值管理机
zuoxiao
2024-03-26 ebc06a3ae3a42bd6ac1359a59c55d5e6f1a0e2f0
app/src/main/java/com/dayu/recharge/tools/NFCWriteHelper.java
@@ -1,22 +1,15 @@
package com.dayu.recharge.tools;
import android.app.Activity;
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 com.dayu.recharge.card.UserCard;
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
@@ -24,16 +17,16 @@
 * email 1058083107@qq.com
 * description
 */
public class NFCWriteHelper extends BaseNFCHelper{
public class NFCWriteHelper extends BaseNFCHelper {
    private Tag tag;
    private NFCWriteHelper.NFCCallback callback;
    private static NFCWriteHelper helper;
    private static int PASSWORD_LENTH = 6;
    private static int PASSWORD_LENTH = 12;
    public NFCWriteHelper(Intent intent) {
    public NFCWriteHelper(Intent intent, Activity activity) {
        super(activity);
        this.tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
    }
    /**
@@ -42,9 +35,9 @@
     * @param intent
     * @return
     */
    public static NFCWriteHelper getInstence(Intent intent) {
    public static NFCWriteHelper getInstence(Intent intent, Activity activity) {
        if (helper == null) {
            helper = new NFCWriteHelper(intent);
            helper = new NFCWriteHelper(intent, activity);
        }
        return helper;
    }
@@ -58,21 +51,83 @@
    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);
                defauleKey[i] = (byte) str.charAt(i);
            }
        }
        return helper;
    }
    /**
     * 写卡
     *
     * @param str      书写内容,16个字节
     * @param a        书写的扇区 (从0开始数)
     * @param b        书写的块(从0开始数)
     * @param callback 返回监听
     * @param userCard 用户卡内容
     * @param
     */
    public void writeData(byte[] str, int a, int b, NFCWriteHelper.NFCCallback callback) {
    public boolean writeUserData(UserCard userCard) {
        if (userCard != null) {
            int a = 1;
            try {
                MifareClassic mfc = MifareClassic.get(tag);
                if (null != mfc) {
                    try {
                        //连接NFC
                        mfc.connect();
                        //验证扇区密码
                        boolean isOpen = mfc.authenticateSectorWithKeyA(a, defauleKey);
                        if (!isOpen) {
                            isOpen = mfc.authenticateSectorWithKeyA(a, companyKey);
                        } else {
                            //写卡时修改所有密码
                            changePasword(a, mfc);
                        }
                        if (isOpen) {
                            for (int b = 0; b < 3; b++) {
                                byte[] data;
                                if (b == 0) {
                                    data = userCard.getZeroBytes();
                                } else if (b == 1) {
                                    data = userCard.getOneBytes();
                                } else {
                                    data = userCard.getTwoBytes();
                                }
                                int bIndex = mfc.sectorToBlock(a);
                                //写卡
                                mfc.writeBlock(bIndex + b, data);
                            }
                            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 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);
        if (str.length <= 16) {
            try {
                MifareClassic mfc = MifareClassic.get(tag);
@@ -84,29 +139,32 @@
                        int count = mfc.getSectorCount();
                        //如果传进来的扇区大了或者小了直接退出方法
                        if (a > count - 1 || a < 0) {
                            callback.isSusses(false);
                            return;
                            return false;
                        }
                        //获取写的扇区的块的数量
                        int bCount = mfc.getBlockCountInSector(a);
                        //如果输入的块大了或者小了也是直接退出
                        if (b > bCount - 1 || b < 0) {
                            callback.isSusses(false);
                            return;
                            return false;
                        }
                        //验证扇区密码
                        boolean isOpen = mfc.authenticateSectorWithKeyA(a, bytes);
                        boolean isOpen = mfc.authenticateSectorWithKeyA(a, defauleKey);
                        if (!isOpen) {
                            isOpen = mfc.authenticateSectorWithKeyA(a, companyKey);
                        } else {
                            //写卡时修改所有密码
                            changePasword(a, mfc);
                        }
                        if (isOpen) {
                            int bIndex = mfc.sectorToBlock(a);
                            //写卡
                            mfc.writeBlock(bIndex + b, str);
                            callback.isSusses(true);
                            return;
                            return true;
                        }
                        callback.isSusses(false);
                        return false;
                    } catch (Exception e) {
                        e.printStackTrace();
                        callback.isSusses(false);
                        return false;
                    } finally {
                        try {
                            mfc.close();
@@ -117,66 +175,68 @@
                }
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        }
        return false;
    }
    /**
     * 修改密码
     *
     * @param password 书写密码,16个字节
     * @param a        书写的扇区
     * @param callback 返回监听
     * @param a 书写的扇区
     *          //     * @param callback 返回监听
     */
    public void changePasword(String password, int a, final NFCWriteHelper.NFCCallback callback) {
        MifareClassic mfc = MifareClassic.get(tag);
    public boolean changePasword(int a, MifareClassic mfc) {
//        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;
                }
//                mfc.connect();
//                int count = mfc.getSectorCount();
//                boolean isOpen = mfc.authenticateSectorWithKeyA(a, defauleKey);
//                //验证是否是默认密码,当默认密码时修改密码
//                if (isOpen) {
                //将密码转换为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);
                byte[] dataA = HexUtil.hexToByteArray(companyKeyA);
                for (int i = 0; i < dataA.length; i++) {
                    data[i] = dataA[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);
                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];
                }
                callback.isSusses(true);
                int bIndex = mfc.sectorToBlock(a);
                int bCount = mfc.getBlockCountInSector(a);
                //写到扇区的最后一个块
                mfc.writeBlock(bIndex + bCount - 1, data);
//                    byte[] dataa = mfc.readBlock(bIndex + bCount - 1);
//                    // 修改密码 A
//                    mfc.writeBlock(mfc.sectorToBlock(a) + 3, dataA);
//                    // 修改密码 B
//                    mfc.writeBlock(mfc.sectorToBlock(a) + 7, dataB);
//                }
                return true;
            } catch (Exception e) {
                e.printStackTrace();
                callback.isSusses(false);
                return false;
//                callback.isSusses(false);
            } finally {
                try {
                    mfc.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
//                try {
//                    mfc.close();
//                } catch (IOException e) {
//                    e.printStackTrace();
//                }
            }
        }
        return false;
    }
    /**