You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Flutter解码越南身份证NFC扫描返回的数据?

越南身份证NFC数据解码解决方案

你当前获取到的只是NFC卡片的基础元数据(比如卡片UID、协议参数),并没有读取到身份证内的个人信息。要获取个人信息,需要通过ISODEP协议发送APDU指令与身份证的内置应用交互,步骤如下:

核心原理

越南身份证基于ISO 7816标准的IC卡,内置了特定的身份信息应用,需要先通过APDU指令选择该应用,再读取对应的数据块来解析个人信息。

具体实现步骤(Flutter)

1. 选择合适的NFC插件

推荐使用nfc_manager或flutter_nfc_kit,两者都支持发送APDU指令。以下示例基于nfc_manager。

2. 配置平台权限

  • Android:在AndroidManifest.xml中添加:
    <uses-permission android:name="android.permission.NFC" />
    <uses-feature android:name="android.hardware.nfc" android:required="true" />
    
  • iOS:在Info.plist中添加:
    <key>NFCReaderUsageDescription</key>
    <string>读取越南身份证信息</string>
    <key>com.apple.developer.nfc.readersession.iso7816.select-identifiers</key>
    <array>
      <string>A0000000724101</string>
    </array>
    

3. 编写APDU交互代码

import 'package:nfc_manager/nfc_manager.dart';
import 'dart:convert';

Future<void> readVietnameseID() async {
  bool nfcAvailable = await NfcManager.instance.isAvailable();
  if (!nfcAvailable) return;

  await NfcManager.instance.startSession(onDiscovered: (NfcTag tag) async {
    // 获取ISODEP通信实例
    Isodep? isodep = Isodep.from(tag);
    if (isodep == null) {
      await NfcManager.instance.stopSession(errorMessage: '不支持ISODEP协议');
      return;
    }

    // 1. 选择越南身份证应用(固定AID:A0000000724101)
    final selectAppApdu = Uint8List.fromList([
      0x00, 0xA4, 0x04, 0x00, // SELECT指令
      0x07, // AID长度
      0xA0, 0x00, 0x00, 0x00, 0x72, 0x41, 0x01, // 越南身份证AID
      0x00 // 响应长度
    ]);

    try {
      // 发送选择应用指令
      NfcResponse selectResponse = await isodep.transceive(selectAppApdu);
      if (selectResponse.statusCode != 0x9000) {
        await NfcManager.instance.stopSession(errorMessage: '选择身份应用失败');
        return;
      }

      // 2. 读取基本信息数据块(示例:读取偏移0x0000开始的32字节,需按规范调整)
      final readDataApdu = Uint8List.fromList([
        0x00, 0xB0, 0x00, 0x00, // READ BINARY指令,偏移地址0x0000
        0x20 // 读取32字节数据
      ]);

      NfcResponse dataResponse = await isodep.transceive(readDataApdu);
      if (dataResponse.statusCode == 0x9000) {
        // 3. 解码数据(越南身份证采用UTF-8编码,字段需按官方规范拆分)
        String rawInfo = utf8.decode(dataResponse.data!);
        print('原始身份数据:$rawInfo');
        // 示例:拆分姓名、身份证号等字段(需参考越南身份证数据规范)
        // String idNumber = rawInfo.substring(0, 12);
        // String fullName = rawInfo.substring(12, 42).trim();
      }

      await NfcManager.instance.stopSession();
    } catch (e) {
      await NfcManager.instance.stopSession(errorMessage: e.toString());
    }
  });
}

关键注意事项

  • 必须使用真机测试,模拟器不支持NFC功能
  • 越南身份证的数据字段偏移、长度需严格遵循官方规范(比如姓名通常从偏移0x04开始,长度30字节;身份证号从偏移0x22开始,长度12字节)
  • 部分敏感数据可能需要PIN验证,但公开的基本信息(姓名、身份证号、出生日期)无需验证
  • 若APDU指令返回错误,检查指令格式是否正确,或卡片是否处于激活状态

内容的提问来源于stack exchange,提问作者Mai Trung Hieu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 00:34:53