Програмування SIM карт

Налаштування SIM карт для приватних LTE мереж.

Наші SIM карти

sysmoISIM-SJA5

Параметр Значення
Чіп 9FV (Infineon)
Формат 2FF, 3FF, 4FF (перфорація)
Профіль ISIM + USIM
Алгоритм Milenage (COMP128v1/v3 опційно)
Кількість профілів 4
ADM ключ За замовчуванням 8 × 0x44

Структура USIM

USIM
├── IMSI — International Mobile Subscriber Identity
├── Ki — Subscriber Authentication Key (128 біт)
├── OPc — Operator Key (derived від OP та Ki)
├── PLMN — Public Land Mobile Network (MCC + MNC)
└── SPN — Service Provider Name

Обладнання

USB PC/SC рідери

Модель Ціна Сумісність
Omnikey 3121 $20 Відмінна
ACR38U $15 Добра
Gemalto IDBridge $25 Відмінна
HID Global $30 Відмінна

Встановлення драйверів

# Linux (PC/SC lite)
sudo apt install pcscd pcsc-tools

# Перевірка рідера
pcsc_scan

# Очікуваний вивід:
# Reader 0: ACS ACR38U-CCID
# Card state: Card inserted

pySim

Встановлення

# Клонувати репозиторій
git clone https://gitea.osmocom.org/sim-card/pysim.git
cd pysim

# Встановити залежності
pip3 install -r requirements.txt

# Або через pip
pip3 install pysim

Базові команди

# Читання ICCID
./pySim-read.py -p 0

# Читання з виводом JSON
./pySim-read.py -p 0 --json

# Інтерактивний режим
./pySim-shell.py -p 0

Параметри SIM

IMSI (International Mobile Subscriber Identity)

Структура: MCC + MNC + MSIN

MCC  Mobile Country Code (3 цифри)
MNC  Mobile Network Code (2-3 цифри)
MSIN  Mobile Subscriber Identification Number

Приклад:
001 01 0000000001
     └── MSIN (унікальний номер)
   └── MNC (тестова мережа)
└── MCC (тестовий код)

Тестові коди:
MCC 001, MNC 01  Test PLMN
MCC 999, MNC 99  Internal test

Ki (Subscriber Authentication Key)

Довжина: 128 біт (16 байт)
Формат: hex string

Приклад:
Ki = 465B5CE8B199B49FAA5F0A2EE238A6BC

Генерація:
openssl rand -hex 16

OPc (Operator Key)

Derivation: OPc = AES(OP, Ki)  OP

Варіанти:
1. Використати спільний OP для всіх SIM
2. Зберігати індивідуальний OPc

Приклад:
OP = E8ED289DEBA952E4283B54E88E6183CA
OPc = E8ED289DEBA952E4283B54E88E6183CA (якщо OP=OPc)

PLMN (Public Land Mobile Network)

Формат в SIM: перевернуті nibbles

MCC=001, MNC=01 → 00 F1 10
MCC=255, MNC=99 → 52 F5 99

Налаштування HPLMN (Home PLMN):
- Має співпадати з eNB
- Визначає home network

Програмування крок за кроком

1. Читання поточних параметрів

./pySim-read.py -p 0

# Вивід:
Reading ...
ICCID: 8988211000000000001
IMSI: 001010000000001
MCC: 001
MNC: 01
...

2. Підготовка параметрів

# Генерація ключів
Ki=$(openssl rand -hex 16)
echo "Ki: $Ki"

# Або використати заздалегідь згенеровані
Ki="465B5CE8B199B49FAA5F0A2EE238A6BC"
OPc="E8ED289DEBA952E4283B54E88E6183CA"

3. Запис на SIM

./pySim-prog.py -p 0 \
  -a 44444444 \
  -x 001 \
  -y 01 \
  -i 001010000000001 \
  -k 465B5CE8B199B49FAA5F0A2EE238A6BC \
  --op E8ED289DEBA952E4283B54E88E6183CA \
  -n "UMTC Test"

# Параметри:
# -a ADM ключ (8 байт)
# -x MCC
# -y MNC
# -i IMSI
# -k Ki
# --op OP (або --opc для OPc)
# -n Service Provider Name

4. Верифікація

# Перечитати SIM
./pySim-read.py -p 0

# Порівняти значення
# IMSI має = 001010000000001
# MCC має = 001
# MNC має = 01

pySim-shell (інтерактивний режим)

Підключення

./pySim-shell.py -p 0

# Prompt:
pySIM-shell (MF)>

Корисні команди

# Навігація
select ADF.USIM
select EF.IMSI

# Читання
read_binary
read_record 1

# Показати дерево
tree

# Інформація про файл
fcp

# Верифікація PIN
verify_chv 1 1234

# Верифікація ADM
verify_adm 44444444

# Зміна IMSI
update_binary 08 09 10 01 00 00 00 00 01

# Вихід
exit

Приклад сесії

pySIM-shell (MF)> select ADF.USIM
pySIM-shell (ADF.USIM)> select EF.IMSI
pySIM-shell (EF.IMSI)> read_binary
{
  "imsi": "001010000000001"
}
pySIM-shell (EF.IMSI)> verify_adm 44444444
pySIM-shell (EF.IMSI)> update_binary 08 09 10 01 00 00 00 00 02
pySIM-shell (EF.IMSI)> read_binary
{
  "imsi": "001010000000002"
}

Інтеграція з Open5GS HSS

Структура запису абонента

# В MongoDB
{
  "imsi": "001010000000001",
  "security": {
    "k": "465B5CE8B199B49FAA5F0A2EE238A6BC",
    "amf": "8000",
    "op": null,
    "opc": "E8ED289DEBA952E4283B54E88E6183CA"
  },
  "ambr": {
    "downlink": { "value": 1, "unit": 3 },
    "uplink": { "value": 1, "unit": 3 }
  },
  "slice": [
    {
      "sst": 1,
      "default_indicator": true,
      "session": [
        {
          "name": "internet",
          "type": 3,
          "qos": { "index": 9, "arp": { ... } },
          "ambr": { ... }
        }
      ]
    }
  ]
}

Додавання через WebUI

1. Відкрити http://localhost:3000
2. Subscriber  Add
3. Заповнити:
   - IMSI: 001010000000001
   - K: 465B5CE8B199B49FAA5F0A2EE238A6BC
   - OPc: E8ED289DEBA952E4283B54E88E6183CA
   - AMF: 8000
4. Save

Додавання через CLI

# Через mongosh
mongosh open5gs

db.subscribers.insertOne({
  "imsi": "001010000000001",
  "security": {
    "k": "465B5CE8B199B49FAA5F0A2EE238A6BC",
    "amf": "8000",
    "op": null,
    "opc": "E8ED289DEBA952E4283B54E88E6183CA"
  },
  "ambr": {
    "downlink": {"value": 1, "unit": 3},
    "uplink": {"value": 1, "unit": 3}
  },
  "slice": [{
    "sst": 1,
    "default_indicator": true,
    "session": [{
      "name": "internet",
      "type": 3,
      "qos": {"index": 9}
    }]
  }]
})

Скрипт масового додавання

#!/usr/bin/env python3
import pymongo
import sys

client = pymongo.MongoClient("mongodb://localhost:27017/")
db = client["open5gs"]

def add_subscriber(imsi, ki, opc):
    subscriber = {
        "imsi": imsi,
        "security": {
            "k": ki,
            "amf": "8000",
            "op": None,
            "opc": opc
        },
        "ambr": {
            "downlink": {"value": 1, "unit": 3},
            "uplink": {"value": 1, "unit": 3}
        },
        "slice": [{
            "sst": 1,
            "default_indicator": True,
            "session": [{
                "name": "internet",
                "type": 3,
                "qos": {"index": 9}
            }]
        }]
    }
    db.subscribers.insert_one(subscriber)
    print(f"Added: {imsi}")

# Приклад
add_subscriber(
    "001010000000001",
    "465B5CE8B199B49FAA5F0A2EE238A6BC",
    "E8ED289DEBA952E4283B54E88E6183CA"
)

Troubleshooting

Рідер не визначається

# Перевірити pcscd
sudo systemctl status pcscd
sudo systemctl restart pcscd

# Перевірити USB
lsusb | grep -i smart

# Права доступу
sudo usermod -aG pcscd $USER
# Перелогінитись

SIM не читається

# Перевірити контакт карти
# Витягнути/вставити SIM

# Перевірити ATR
pcsc_scan
# Має показати ATR карти

# Спробувати інший рідер

Помилка ADM

Error: SW 6982 (Security status not satisfied)

Причина: Неправильний ADM ключ
Дії:
1. Перевірити ADM (за замовчуванням 8 × 0x44 = "44444444")
2. Не вводити більше 3 разів неправильно!
3. Запитати виробника якщо невідомий

SIM заблокована

PIN/PUK заблокована:
1. Знайти PUK код
2. Розблокувати через телефон
3. Або через pySim:
   ./pySim-shell.py -p 0
   > unblock_chv 1 12345678 1234

Не працює в мережі

1. Перевірити PLMN (MCC/MNC)
   - На SIM
   - В конфігурації eNB
   - В Open5GS

2. Перевірити Ki/OPc
   - На SIM
   - В Open5GS HSS

3. Перевірити IMSI
   - Формат: 15 цифр
   - Додано в HSS

4. Логи Open5GS
   tail -f /var/log/open5gs/hss.log

Безпека

Зберігання ключів

Ki та OPc — критична інформація!

✓ Зашифрована база даних
✓ Обмежений доступ
✓ Backup в безпечному місці

✗ Не зберігати в plaintext
✗ Не передавати незашифровано
✗ Не commit в git

Аудит

# Список всіх SIM в системі
mongosh open5gs --eval "db.subscribers.find({}, {imsi: 1})"

# Перевірка дублікатів IMSI
mongosh open5gs --eval "db.subscribers.aggregate([
  {\$group: {_id: '\$imsi', count: {\$sum: 1}}},
  {\$match: {count: {\$gt: 1}}}
])"

Шлях: lte/sim-programming.md

UMTC Wiki © 2026 | Ukrainian Military Tactical Communications