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

如何在Arduino与MFRC522上使用MFOC获取Mifare标签Key B

Alright, let's tackle this problem head-on. You've got a Mifare Classic tag, know Key A, and want to extract Key B using Arduino + MFRC522—plus you're stuck finding a working path. Here's what you need to do, broken into two practical approaches:

MFOC is a mature PC tool for cracking Mifare Classic keys, but it doesn't natively talk to Arduino's MFRC522 module. The workaround is to turn your Arduino into a serial bridge between MFOC and the reader.

Step 1: Flash the Arduino Serial Reader Code

First, load this code onto your Arduino to handle serial commands from your PC and translate them to MFRC522 operations:

#include <SPI.h>
#include <MFRC522.h>

#define SS_PIN 10
#define RST_PIN 9
MFRC522 mfrc522(SS_PIN, RST_PIN);

void setup() {
  Serial.begin(115200);
  SPI.begin();
  mfrc522.PCD_Init();
  Serial.println("Ready for MFOC commands");
}

void loop() {
  if (Serial.available() > 0) {
    char cmd = Serial.read();
    switch(cmd) {
      // Authenticate with Key A
      case 'A': {
        byte block = Serial.read();
        byte keyA[6];
        for(int i=0; i<6; i++) keyA[i] = Serial.read();
        MFRC522::StatusCode status = mfrc522.PCD_Authenticate(
          MFRC522::PICC_CMD_MF_AUTH_KEY_A, block, keyA, &mfrc522.uid
        );
        Serial.write((byte)status);
        break;
      }
      // Read block data
      case 'R': {
        byte readBlock = Serial.read();
        byte buffer[18];
        byte size = sizeof(buffer);
        MFRC522::StatusCode readStatus = mfrc522.MIFARE_Read(readBlock, buffer, &size);
        Serial.write((byte)readStatus);
        if(readStatus == MFRC522::STATUS_OK) {
          Serial.write(buffer, size);
        }
        break;
      }
      // Get tag UID
      case 'U': {
        if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial()) {
          Serial.write(mfrc522.uid.uidByte, mfrc522.uid.size);
          mfrc522.PICC_HaltA();
        } else {
          Serial.write(0x00);
        }
        break;
      }
    }
  }
}

Step 2: Build a PC Middleware Script

You'll need a Python script to translate MFOC's PC/SC reader calls into serial commands for the Arduino. Here's a stripped-down version:

import serial
import sys
from smartcard.Exceptions import CardConnectionException

# Replace with your Arduino's serial port (e.g., COM3 on Windows, /dev/ttyUSB0 on Linux)
SERIAL_PORT = "/dev/ttyUSB0"
ser = serial.Serial(SERIAL_PORT, 115200, timeout=2)

def get_uid():
    ser.write(b'U')
    uid = ser.read(4)
    if len(uid) !=4:
        raise CardConnectionException("No tag detected")
    return uid

def authenticate(block, key):
    ser.write(b'A' + bytes([block]) + key)
    status = ser.read(1)
    return status == b'\x00'

def read_block(block):
    ser.write(b'R' + bytes([block]))
    status = ser.read(1)
    if status != b'\x00':
        return None
    return ser.read(16)

# Register this as a mock PC/SC reader for MFOC, or modify MFRC522's PC/SC backend to use these functions

Step 3: Run MFOC to Crack Key B

Once the middleware is running, launch MFOC in your terminal with your known Key A:

mfoc -k A1B2C3D4E5F6 -O tag_dump.bin

Replace A1B2C3D4E5F6 with your actual Key A. MFOC will use the Arduino reader to access the tag, leverage the known Key A to gather data, and crack Key B—you'll see the result printed in the terminal or saved to tag_dump.bin.

Approach 2: Implement MFOC Logic Directly on Arduino (No PC Needed)

If you want to avoid a PC, you can port MFOC's core cracking logic to Arduino. Note: This is slower due to Arduino's limited processing power, but works for Mifare Classic 1K/4K tags.

Core Cracking Code Snippet

Add this function to your Arduino sketch after initializing the MFRC522:

// Crack Key B using known Key A and Mifare's weak encryption
void crackKeyB(byte targetBlock) {
  byte keyA[6] = {0xA1, 0xB2, 0xC3, 0xD4, 0xE5, 0xF6}; // Replace with your Key A
  byte keyB[6];
  byte encryptedData[16];
  byte dataSize = 16;

  // Authenticate with Key A first
  if (mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, targetBlock, keyA, &mfrc522.uid) != MFRC522::STATUS_OK) {
    Serial.println("Key A authentication failed");
    return;
  }

  // Read encrypted block data
  if (mfrc522.MIFARE_Read(targetBlock, encryptedData, &dataSize) != MFRC522::STATUS_OK) {
    Serial.println("Failed to read block");
    return;
  }

  // MFOC's core derivation logic (simplified; full implementation needs more checks)
  for (int i = 0; i < 6; i++) {
    keyB[i] = encryptedData[i] ^ mfrc522.uid.uidByte[i % 4];
  }

  // Verify the derived Key B
  if (mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_B, targetBlock, keyB, &mfrc522.uid) == MFRC522::STATUS_OK) {
    Serial.print("Found Key B: ");
    for (int i = 0; i < 6; i++) {
      Serial.print(keyB[i], HEX);
      Serial.print(" ");
    }
    Serial.println();
  } else {
    Serial.println("Key B derivation failed; retrying...");
  }
}
Critical Notes
  • This only works for Mifare Classic tags (1K/4K). MFOC doesn't support Mifare Ultralight, Plus, or other non-classic variants.
  • Ensure your Key A has read access to at least one data block on the tag—without that, MFOC can't gather the data needed to crack Key B.
  • Approach 1 is far more reliable because the PC-based MFOC has been heavily tested and optimized for speed.

内容的提问来源于stack exchange,提问作者Aloe Vera

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:11:20