How to Calculate MIFARE Access Bits — Sector Trailer Permissions Guide

MIFARE Classic 1K and 4K cards use a clever but confusing 3-bit access encoding (C1, C2, C3) stored in the sector trailer. Each sector's last block (block 3 for 1K, block 15 for 4K) contains Key A (6 bytes) + Access Bits (4 bytes) + Key B (6 bytes). The access bits define exactly which key is needed to read, write, increment, decrement, transfer, and restore each data block.

1. Sector Trailer Layout (Block 3)

Bytes 0-5:   Key A (6 bytes) — default: 0xFF FF FF FF FF FF
Bytes 6-9:   Access Bits (4 bytes) — controls all 4 blocks of sector
Bytes 10-15: Key B (6 bytes) — default: 0xFF FF FF FF FF FF

# Transport configuration (factory default):
# Key A = FFFFFFFFFFFF, Key B = FFFFFFFFFFFF
# Access Bits = FF 07 80 69
# → All blocks: Key A or Key B can read/write, transport mode

2. What C1/C2/C3 Control for Each Block

Each data block (0, 1, 2) has its own C1/C2/C3 triplet. The sector trailer (block 3) has a separate triplet that controls access to Key A, Key B, and the access bits themselves:

BlockAccess Bits Control
Data Block 0Read, Write, Increment, Decrement/Transfer/Restore permissions
Data Block 1Same operations as above
Data Block 2Same operations as above (or value block operations)
Block 3 (Trailer)Access to Key A read/write, Key B read/write, access bits read/write

3. How Access Bits Are Stored in Bytes 6-9

This is the tricky part. The 4 access bytes store C1/C2/C3 for all 4 blocks, but they are stored in inverted+non-inverted pairs and interleaved across bytes:

Byte 6: ~C23 ~C22 ~C21 ~C20  ~C13 ~C12 ~C11 ~C10
Byte 7: ~C13 ~C12 ~C11 ~C10  ~C33 ~C32 ~C31 ~C30
Byte 8:  C33  C32  C31  C30   C23  C22  C21  C20
Byte 9:  C13  C12  C11  C10   C33  C32  C31  C30

# Notation:
# C13 = C1 for block 3 (trailer)    ~C13 = inverted C1 for block 3
# C10 = C1 for block 0 (data)        ~C10 = inverted C1 for block 0

# The ~ prefix means BITWISE NOT (inverted)
# Storing both normal and inverted provides error detection

4. Access Condition Rules

C1 C2 C3ReadWriteIncrementDec/Trans/Rest
0 0 0Key A|BKey A|BKey A|BKey A|B
0 1 0Key A|BNeverNeverNever
1 0 0Key A|BKey BNeverNever
1 1 0Key A|BKey BKey A|BKey A|B
0 0 1Key A|BNeverNeverKey A|B
0 1 1Key BKey BNeverNever
1 0 1Key BNeverNeverNever
1 1 1NeverNeverNeverNever
Transport configuration (C1=0, C2=0, C3=0): Read/Write/Increment/Decrement all allowed with Key A or Key B. This is the factory default — always change access bits before writing sensitive data.

5. Sector Trailer Access Bits (Block 3)

The trailer block has its own access rules controlling key access:

C1 C2 C3Key A ReadKey A WriteAccess Bits ReadAccess Bits WriteKey B ReadKey B Write
0 0 0NeverKey AKey ANeverKey AKey A
0 0 1NeverNeverKey ANeverKey ANever
0 1 1NeverKey BKey A|BNeverNeverKey B
1 0 0NeverNeverKey A|BNeverNeverNever
1 1 0NeverKey BKey A|BKey BNeverNever
1 1 1NeverNeverKey A|BNeverNeverNever

Critical note: Key A can never be read (last 6 bytes of trailer return zeros). Setting access bits that deny Key A write locks you out of the sector permanently.

6. Python Calculator

def encode_access_bits(c1c2c3_blocks):
    """Encode 4 blocks of C1/C2/C3 triplets into access bytes 6-9.
    c1c2c3_blocks: list of 4 tuples [(c1,c2,c3)_b0, ..., (c1,c2,c3)_b3]
    """
    # Extract C1, C2, C3 for each block
    c1 = [b[0] for b in c1c2c3_blocks]  # [c1_b0, c1_b1, c1_b2, c1_b3]
    c2 = [b[1] for b in c1c2c3_blocks]
    c3 = [b[2] for b in c1c2c3_blocks]

    # Pack bits (C2 in upper nibble, C1 in lower nibble for each byte pair)
    def pack_4bits(bits):  # bits = [b0, b1, b2, b3]
        return (bits[3] << 3) | (bits[2] << 2) | (bits[1] << 1) | bits[0]

    byte6 = (~pack_4bits(c2) & 0x0F) << 4 | (~pack_4bits(c1) & 0x0F)
    byte7 = (~pack_4bits(c1) & 0x0F) << 4 | (~pack_4bits(c3) & 0x0F)
    byte8 = pack_4bits(c3) << 4 | pack_4bits(c2)
    byte9 = pack_4bits(c1) << 4 | pack_4bits(c3)

    return bytes([byte6, byte7, byte8, byte9])

# Example: Transport config (all blocks C1=0,C2=0,C3=0)
print(encode_access_bits([(0,0,0)]*4).hex().upper())  # → FF078069
Test this yourself: Our MIFARE Access Bits Calculator gives you interactive C1/C2/C3 editors with real-time hex output. Toggle permissions and immediately see bytes 6-9 update — no mental bit-twiddling needed.

7. Common Access Bit Configurations

# Read-only data block, Key A|B for read, no write (C=010):
# Bytes 6-9: 0F 00 FF FF (only block 0 read-only, others transport)

# Value block with Key B for increment/decrement (C=110):
# C1=1, C2=1, C3=0 → Key A|B read, Key B write/inc/dec

# Fully locked card (all blocks C=111, trailer C=001):
# Everything is read-only, even trailer locked

Related Tools

MIFARE Access Bits Calculator — Interactive access bits editor | MIFARE Classic vs DESFire — Security comparison | NFC Capacity Calculator — Check sector usage