Mifare Ultralight C 3DES认证过程中通信断开问题求助
Mifare Ultralight C 3DES认证过程中通信断开问题求助
我目前在实现Mifare Ultralight C卡的3DES认证流程,第一步发送1A 00认证命令一切正常,能收到AF开头带8字节挑战的响应,但当我发送AF+16字节加密后的响应 payload 时,NFC设备直接断开连接了,完全不知道问题出在哪。我使用的是Flutter的flutter_nfc_kit插件和pointycastle加密库,以下是我的完整代码和调试日志:
实现代码
import 'package:flutter_nfc_kit/flutter_nfc_kit.dart'; import 'package:pointycastle/pointycastle.dart'; import 'dart:typed_data'; import 'dart:math'; Future<bool> _authenticateUltralightC() async { final Uint8List key = Uint8List.fromList(List.filled(16, 0x00)); // 默认密钥 Uint8List iv = Uint8List(8); // 初始IV(全0) try { // 步骤1: 发送认证命令 Uint8List authCmd = Uint8List.fromList([0x1A, 0x00]); print('Auth Command: ${_bytesToHex(authCmd)}'); Uint8List response = await FlutterNfcKit.transceive(authCmd); print('Auth Response: ${_bytesToHex(response)}'); if (response.length != 9 || response[0] != 0xAF) { print('Error: Invalid response format'); return false; } // 步骤2: 解密RndB final rndBEnc = response.sublist(1, 9); final rndB = _tripleDesDecrypt(rndBEnc, key, iv); print('RndB decrypted: ${_bytesToHex(rndB)}'); // 更新IV用于下一步加密 iv = rndBEnc; // 步骤3: 生成RndA并准备payload final rndA = _generateRandomBytes(8); final rndBRot = Uint8List.fromList([...rndB.sublist(1), rndB[0]]); final payload = Uint8List.fromList([...rndA, ...rndBRot]); print('RndA: ${_bytesToHex(rndA)}'); print('RndB rotated: ${_bytesToHex(rndBRot)}'); print('Payload: ${_bytesToHex(payload)}'); // 加密payload final payloadEnc = _tripleDesEncrypt(payload, key, iv); print('Payload encrypted: ${_bytesToHex(payloadEnc)}'); // 问题出在这一步:发送0xAF + 16字节加密数据(按官方协议) Uint8List step2Cmd = Uint8List.fromList([0xAF, ...payloadEnc]); print('Step2 Command (17 bytes): ${_bytesToHex(step2Cmd)}'); // 执行到这里直接断开连接,后续代码完全不会执行 response = await FlutterNfcKit.transceive(step2Cmd); print('Step2 Response: ${_bytesToHex(response)}'); return true; } catch (e) { print('Auth error: $e'); return false; } } // 3DES加密工具函数 Uint8List _tripleDesEncrypt(Uint8List data, Uint8List key, Uint8List iv) { // 将16字节密钥转换为24字节(K1, K2, K1) final key24 = Uint8List.fromList([...key, ...key.sublist(0, 8)]); final engine = DESedeEngine(); final cipher = CBCBlockCipher(engine); cipher.init(true, ParametersWithIV(KeyParameter(key24), iv)); final output = Uint8List(data.length); for (var offset = 0; offset < data.length; offset += 8) { cipher.processBlock(data, offset, output, offset); } return output; } // 3DES解密工具函数 Uint8List _tripleDesDecrypt(Uint8List data, Uint8List key, Uint8List iv) { final key24 = Uint8List.fromList([...key, ...key.sublist(0, 8)]); final engine = DESedeEngine(); final cipher = CBCBlockCipher(engine); cipher.init(false, ParametersWithIV(KeyParameter(key24), iv)); final output = Uint8List(data.length); for (var offset = 0; offset < data.length; offset += 8) { cipher.processBlock(data, offset, output, offset); } return output; } // 生成随机字节 Uint8List _generateRandomBytes(int length) { final random = SecureRandom('Fortuna'); final seedBytes = Uint8List(32); final now = DateTime.now().millisecondsSinceEpoch; for (int i = 0; i < 32; i++) { seedBytes[i] = (now + i) % 256; } random.seed(KeyParameter(seedBytes)); return random.nextBytes(length); } // 字节转十六进制字符串 String _bytesToHex(Uint8List bytes) { return bytes.map((b) => b.toRadixString(16).padLeft(2, '0')).join(' ').toUpperCase(); }
调试日志
I (10685): Auth Command: 1A 00 /flutter I (10685): Auth Response: AF 1D B0 CA 48 03 29 5A 49 /flutter I (10685): RndB encrypted: 1D B0 CA 48 03 29 5A 49 /flutter I (10685): RndB decrypted: 7C 18 E3 C7 AE 81 60 18 /flutter I (10685): RndA generated: 3C 1E 9A D6 B3 C9 C7 0E /flutter I (10685): RndB rotated: 18 E3 C7 AE 81 60 18 7C /flutter I (10685): Payload (RndA + RndB'): 3C 1E 9A D6 B3 C9 C7 0E 18 E3 C7 AE 81 60 18 7C /flutter I (10685): IV for encryption: 1D B0 CA 48 03 29 5A 49 /flutter I (10685): Payload encrypted: 7B 10 0B 0F A5 3B D2 1B D7 AD 4B 8E A8 32 F2 0E /flutter I (10685): Step2 Command: AF 7B 10 0B 0F A5 3B D2 1B D7 AD 4B 8E A8 32 F2 0E /flutter E(10685): Transceive: AF7B100B0FA53BD21BD7AD4B8EA832F20E error /im.nfc.flutter_nfc_kit.FlutterNfcKitPlugin E(10685): java.lang.reflect.InvocationTargetException /im.nfc.flutter_nfc_kit.FlutterNfcKitPlugin E(10685): at java.lang.reflect.Method.invoke(Native Method) /im.nfc.flutter_nfc_kit.FlutterNfcKitPlugin E(10685): at im.nfc.flutter_nfc_kit.FlutterNfcKitPlugin$Companion.transceive(FlutterNfcKitPlugin.kt:71) /im.nfc.flutter_nfc_kit.FlutterNfcKitPlugin E(10685): at im.nfc.flutter_nfc_kit.FlutterNfcKitPlugin$Companion.access$transceive(FlutterNfcKitPlugin.kt:42) /im.nfc.flutter_nfc_kit.FlutterNfcKitPlugin E(10685): at im.nfc.flutter_nfc_kit.FlutterNfcKitPlugin.handleMethodCall$lambda$4(FlutterNfcKitPlugin.kt:363) /im.nfc.flutter_nfc_kit.FlutterNfcKitPlugin E(10685): at im.nfc.flutter_nfc_kit.FlutterNfcKitPlugin.$r8$lambda$HBcA1lvz_kCygGP5Zr_3a09ChIw(Unknown Source:0) /im.nfc.flutter_nfc_kit.FlutterNfcKitPlugin E(10685): at im.nfc.flutter_nfc_kit.FlutterNfcKitPlugin$$ExternalSyntheticLambda4.run(Unknown Source:24) /im.nfc.flutter_nfc_kit.FlutterNfcKitPlugin E(10685): at android.os.Handler.handleCallback(Handler.java:942) /im.nfc.flutter_nfc_kit.FlutterNfcKitPlugin E(10685): at android.os.Handler.dispatchMessage(Handler.java:99) /im.nfc.flutter_nfc_kit.FlutterNfcKitPlugin E(10685): at android.os.Looper.loopOnce(Looper.java:201) /im.nfc.flutter_nfc_kit.FlutterNfcKitPlugin E(10685): at android.os.Looper.loop(Looper.java:288) /im.nfc.flutter_nfc_kit.FlutterNfcKitPlugin E(10685): at android.os.HandlerThread.run(HandlerThread.java:67)
我对照官方协议检查了好几遍流程:解密RndB、生成RndA、旋转RndB后拼接成16字节 payload、用3DES-CBC模式加密(密钥转成24字节的K1-K2-K1格式)、最后加上0xAF发送,逻辑上应该没问题,但就是在发送第二步命令时直接断开了。有没有大佬能帮我排查下?比如加密模式、IV的处理、命令格式有没有哪里不符合NFC卡的要求?
内容来源于stack exchange
相关产品推荐
相关产品推荐

