imageОсновные действующие лица перечислены в заголовке, а в результате мы получим прототип простой системы контроля доступа на основе точно такого RFID модуля RC522, которую можно использовать не только для открывания двери, но и выполнения любого аналогичного действия путем подачи и прекращения подачи управляющего сигнала.

В виде наличия множество разнообразной информации в интернете с не совсем рабочими примерами, постараюсь описать все пошагово и подробно. Данный модуль работает с RFID картами на частоте 13,56 МГц и легко понимает кроме карт и чипов с такой частотой, ещё и единые проездные билеты Москвы (я использовал использованный одноразовый единый билет), а также NFC-метки.

Hardware


Для реализации проекта, необходимо подключить модуль и несколько дополнительных компонентов.
Схема подключения модуля
image

Для проверки работы модуля я использовал несколько диодов и пьезодинамик. Красный и зеленый диоды — для индикации состояния работы условного замка (красный — замок закрыт, зеленый — замок открыт), желтый диод — для индикации управляющего сигнала (в реальных условиях будет заменен на замок), пьезодинамик — подает звуковой сигнал во время открытия замка и сигнализирует об ошибке. В реальной схеме с замком целесообразно использовать реле для управления цепью питания замка.
Схема подключения диодов и динамика
image


Software


Для начала необходимо включить SPI на Raspberry, если не включен. Как это сделать, написано здесь.
Теперь можно скачать библиотеку для работы с нашим модулем и проверить чтение и запись карт. Для нас важно чтение, в частности чтение UID карты, для этого вводим в консоли:
git clone https://github.com/mxgxw/MFRC522-python

Для корректной работы скачанного кода необходимо также скачать и установить SPI-py:
git clone https://github.com/lthiery/SPI-Py
sudo python /SPI-Py/setup.py install

Теперь можно считывать UID карты и записанную в неё информацию. Для этого запускаем их загруженных нами файлов пример:
cd MFRC522-python
sudo python Read.py

На экране должно появиться:
Welcome to the MFRC522 data read example
Press Ctrl-C to stop.

После этого можно поднести к считывателю карточку или метку и мы увидим её UID
Card detected
Card read UID: 60,56,197,101
Size: 8
Sector 8 [12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

В данном случае нас интересует эта часть: UID: 60,56,197,101.
А эту часть мы можем изменять
Заголовок спойлера
, заменяя нули нужными нам значениями: Sector 8 [12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], но это нас сейчас не интересует.

Далее для работы нашего модуля и прочих компонентов я написал простенький скрипт на языке python на основе различных источников.

Скрипт с моими комментариями
#!/usr/bin/env python

import RPi.GPIO as GPIO
import MFRC522
import signal
import time

red = 11
green = 18
speaker = 16
doorlock = 12

# Список UID карт (UID карты узнаем с помощью sudo python /MFRC522-python/Read.py
card_01 = '6056197101' #white
card_02 = '148167101184' #fob
card_03 = '13652116101' #единый

#Настройка портов вывода
GPIO.setmode(GPIO.BOARD) # Это значит, что считаем пины по порядку с левого верхнего (3v3 - первый)
GPIO.setup(red, GPIO.OUT, initial=1) # Устанавливаем пин 18 на вывод
GPIO.setup(green, GPIO.OUT, initial=0) # тоже самое с пином 11
GPIO.setup(speaker, GPIO.OUT, initial=0) # пин 16
GPIO.setup(doorlock, GPIO.OUT, initial=0) # пин 12

continue_reading = True

def end_read(signal,frame): # что делать, если программу прервать и как её прервать
    global continue_reading
    print "Ctrl+C captured, ending read."
    continue_reading = False
    GPIO.cleanup()

# Create an object of the class MFRC522 (??)
MIFAREReader = MFRC522.MFRC522()

while continue_reading:

# Сканируем карты - считываем их UID
    (status,TagType) = MIFAREReader.MFRC522_Request(MIFAREReader.PICC_REQIDL)

    # Если карту удалось считать, пишем "карта найдена"
    if status == MIFAREReader.MI_OK:
        print "Card detected"

    # Считываем UID карты
    (status,uid) = MIFAREReader.MFRC522_Anticoll()

    # Если считали UID, то идем дальше
    if status == MIFAREReader.MI_OK:
        # выводим UID карты на экран
        UIDcode = str(uid[0])+str(uid[1])+str(uid[2])+str(uid[3])
        print UIDcode

        # Если карта есть в списке
        if UIDcode == card_01 or UIDcode == card_03 or UIDcode == card_02:
        # то дверь открывается
        # предполагается, что замок открывается при подаче на
        # него (на реле, управляющее замком), напряжения
        # т.е. им управляет переключаемое реле
        # т.е. замок открывается при высоком значении пина doorlock
        # при этом, горит зеленая, тухнет красная и пищит динамик

                GPIO.output((red, green, speaker, doorlock), (0,1,1,1))
                print "Door open"

                # успеть дернуть за 1 секунду
                time.sleep(1)
                GPIO.output((red, green, speaker, doorlock), (1,0,0,0))

                # потом дверь закрывается, о чем нас извещают
                print "Door closed"

        # А если карты в списке нет, то моргаем и пищим
        else:
                GPIO.output((red, green, speaker, doorlock), (1,0,0,0))
                time.sleep(0.05)
                GPIO.output((red, green, speaker, doorlock), (1,0,1,0))
                time.sleep(0.05)
                GPIO.output((red, green, speaker, doorlock), (1,0,0,0))
                time.sleep(0.05)
                GPIO.output((red, green, speaker, doorlock), (1,0,1,0))
                time.sleep(0.05)
                GPIO.output((red, green, speaker, doorlock), (0,1,0,0))
                time.sleep(0.05)
                GPIO.output((red, green, speaker, doorlock), (0,1,1,0))
                time.sleep(0.05)
                GPIO.output((red, green, speaker, doorlock), (0,1,0,0))
                time.sleep(0.05)
                GPIO.output((red, green, speaker, doorlock), (0,1,1,0))
                time.sleep(0.05)
                GPIO.output((red, green, speaker, doorlock), (1,0,0,0))
                time.sleep(0.05)
                GPIO.output((red, green, speaker, doorlock), (1,0,1,0))
                time.sleep(0.05)
                GPIO.output((red, green, speaker, doorlock), (1,0,0,0))
                time.sleep(0.05)
 		GPIO.output((red, green, speaker, doorlock), (1,0,1,0))
                time.sleep(0.05)
                GPIO.output((red, green, speaker, doorlock), (0,1,0,0))
                time.sleep(0.05)
                GPIO.output((red, green, speaker, doorlock), (0,1,1,0))
                time.sleep(0.05)
                GPIO.output((red, green, speaker, doorlock), (0,1,0,0))
                time.sleep(0.05)
                GPIO.output((red, green, speaker, doorlock), (0,1,1,0))
                time.sleep(0.05)
                GPIO.output((red, green, speaker, doorlock), (1,0,0,0))
                print "Unrecognised Card"



Создаем файл и копируем в него код:
nano rf.py

сохраняем файл (CTRL+x, y).
Запускаем скрипт командой
sudo python rf.py

После будет происходить следующее:
красный диод загорится, отображая, что наш «замок» закрыт.
Если к считывателю поднесена карта, номер которой (без запятых) внесен в список, то красный диод потухнет, зеленый диод загорится, сигнализируя, что «замок» открыт, желтый диод загорится — он в данном случае «контрольный», показывая, что на «замок» идет управляющий сигнал, пьезодинамик запищит. Через заданное время (в нашем случае 1 секунду) диоды и динамик вернутся к исходному состоянию, считыватель будет ожидать считывания карты.
Если к считывателю поднесена карта не из списка, то красный и зеленый диод будут мигать, пьезодинамик будет прерывисто пищать, сигнализируя ошибку, желтый диод не загорится (т.е. сигнал на открытие «замка» не идет). Чуть меньше чем через секунду все вернется к исходному состоянию.

Короткое видео, иллюстрирующее работу:

Комментарии (18)


  1. Hellsy22
    23.02.2016 01:25

    del


  1. Hellsy22
    23.02.2016 01:32
    +4

    Сделал в свое время дома "интернет по карточкам": при поднесении карты к ридеру — интернет ребенку блокировался, при повторном поднесении — разблокировался.

    Возиться с библиотеками мне было лень, поэтому скрипт опирался на утилиту nfc-list и выглядел вот так:

    #!/usr/bin/perl
    
    use Time::HiRes qw (usleep gettimeofday);
    
    my $drop = 0;
    
    while (1) {
        my $t = gettimeofday();
        my $r = `nfc-list`;
        if ($r=~/UID \(NFCID1\): ((?:\w\w\s+)+)/) {
            my $uid = uc $1;
            $uid =~s/\s+//g;
            print "UID: $uid\n";
            if ($uid eq '34591709856866') {
                if ($drop) {.
                    `iptables -D INPUT -d 192.168.10.22 -j DROP`;
                    `iptables -D FORWARD -d 192.168.10.22 -j DROP`;
                    print "Drop block\n";
                    $drop = 0;
                } else {
                    `iptables -I INPUT -d 192.168.10.22 -j DROP`;
                    `iptables -I FORWARD -d 192.168.10.22 -j DROP`;
                    print "Add block\n";
                    $drop = 1;
                }
                sleep 3;
            }
        }
    
        usleep 300000 if (gettimeofday() - $t < 1000000 );
    }

    Позже для этих же целей использовалось nfc-кольцо. Но это все для развлечения, потому как не стоит доверять безопасность простому id, который может кто угодно считать с расстояния. По тем же причинам не стоит использовать Mifare Ultralight. Нужно брать карту типа Mifare 1k или 4k и создавать правильную пару запрос-ответ.

    P.S.: А что случилось с редактированием? Все тэги и кавычки покорежило в первом комментарии.


    1. v-milenin
      23.02.2016 01:40

      Ну да, главную дверь в дом я бы такой штуке не доверил. Это так, изучение технологии..


      1. x_sourer
        23.02.2016 13:53

        Аха, дом можно и обесточить и все двери будут открыты, вариант — аккумулятор, но на долго ли хватит?


        1. Hellsy22
          23.02.2016 16:14
          +2

          Если магнитный замок — на 16 часов. Если электропривод — то вообще без разницы. А еще есть гибридные замки, которые открываются ключом, пинкодом и картой и работают на обычных аккумуляторах по полгода.


        1. dkv
          23.02.2016 22:16

          Смотря что запитывать от аккумулятора. Если это лишь контроллер доступа + электромагнитная защёлка, на которую импульс подаётся лишь на время открытия — то вполне может дождаться вас из турпоездки и открыть вам дверь. Если это малина с линухом на бору, всё время занятая анализом видео с вашего дверного глазка в поисках на нём котиков, то хватит часов на пять. Это всё если говорить о стандартном аккумуляторе в 7 Ач.
          А вообще, если и баловаться со СКУД у себя дома, то ставить замки, имеющие возможность открываться-закрываться механически с ключа. и не разблокирующие двери при снятии напряжения. В организациях ситуация обратная, что продиктовано нормами пожарной безопасности.


      1. bazis13
        24.02.2016 11:48

        Т.е. беспроводным карточкам с шифрованием вы не доверяете, а железной болванке с определенным набором дырочек — да?
        Причем на ютюбе полно роликов, где описано, как можно вскрыть любой механический замок — технологии тысячи лет, всё давно отлажено.


        1. v-milenin
          24.02.2016 12:50

          Здесь нужно взвесить за и против:
          Карточка — легко скопировал, находясь недалеко от карты, пришел, ткнул в считыватель, дверь открылась
          Ключ — тоже легко скопировать, но нужны навыки, физический доступ к ключу.

          Замок карточный — при отсутствии аварийного питания — открылся (в случае, если он открывается при отсутствии напряжения — как в подъезде, например). Т.е. тихонько отключил свет издалека, пришел, открыл дверь.
          Замок механический — открыть можно, но нужно физический доступ к замку на какое-то время, возможно шум, останутся следы взлома.

          Это на первый взгляд. Конечно, каждый из этих недостатков можно нивелировать, но мне спокойнее было бы все-таки с механическим замком.
          Это примерно как с деньгами в банке и наличными — вроде наличные легко украсть (сунул руку в карман и забрал), но на деле это не так просто сделать. А путем взлома банка — доступ к деньгам не нужен. Понятно, что и первый и второй вариант сложны в реализации, но кому-то спокойнее, когда они дома в ящике с носками лежат...


          1. bazis13
            24.02.2016 12:59

            Карты метро копируются только на специальные дорогие болванки. Для этого нужны такие особые знания, что у взломщика должно быть очень большое желание и интеллект. Чтобы купить и использовать отмычки, много ума не надо.
            Плюс можно использовать перезаписываемые блоки на карте, чтобы хранить там дополнительные изменяемые данные для проверки.

            Замок — электромеханический. Сам по себе не открывается, питание от UPS.
            При открывании карточкой легко добавить фичу с уведомлением на телефон: «Дверь открыл вася.» или «Неизвестная карта была рядом со считывателем».
            С механическим ключом это просто невозможно.
            Я вот не могу находится в спокойствии, когда не знаю, ковыряет сейчас кто-то замок отмычкой или нет. В случае с картой и ковырять нечего — ридер можно замуровать в стену рядом с дверью.


            1. v-milenin
              24.02.2016 13:07

              Спорить не буду, технология удобная,- согласен. И в плане пользования и в плане контроля.
              Про карточки метро только добавлю: UID карточки скопировать можно китайским копиром, поддерживающим стандарт 13.56 МГц на дешевую болванку — только что проверил, получилось. Информацию на неё перезаписать сложнее.


              1. bazis13
                24.02.2016 13:15

                Это странно.
                Вот https://toster.ru/q/43804 пишут
                «В реальной жизни основная проблема копирования Mifare Classic и Ultralight состоит в том, что UID на этих картах прошивается на заводе, он уникален для каждой карты и не изменяем. И даже есть у вас есть белый пластик и есть все ключи(для Classic-а), то повторить его полностью вы не сможете из-за того же UID-а. „

                И тут https://habrahabr.ru/post/175557/
                “Здесь я рассмотрю структуру карт Mifare 1k и 4k. Карта 1k разделена на 16 секторов, от 0 до 15. Нулевой сектор, это блок производителя, в котором записан индивидуальный серийный номер карты UID он прописывается на производстве и не поддаётся изменению. Остальные 15 секторов доступны для считывания/записи. „

                Китайцы продавали неправильные болванки, которым можно изменять UID, но стоили они дорого.


                1. v-milenin
                  24.02.2016 13:42

                  Покупал пару лет назад копир для карточек долларов за 15,- к нему в комплекте прилагались 5 белых карточек (125 Гц) и 5 чипов синеньких (13,56 МГц). И те и другие позволяют переписать их заводской UID — только что перепроверил. UID карты метро на чип записать удалось. Мне кажется, ключники, которые домофонные ключи копируют такие болванки используют.


    1. MrFrizzy
      23.02.2016 21:01

      А не подскажете, что использовали для считывания nfc? Все usb readers на aliexpress стоят дорого, выглядят кустарными поделками и места занимают много из-за рамки...


      1. Hellsy22
        23.02.2016 21:35
        +1

        ACR122U за ~35$.


    1. Axino
      24.02.2016 12:06

      Карты серии Сlassic, в том числе 1к и 4к, тоже нельзя считать безопасными, так как там использована слабая криптозащита. На Хабре есть пост, в котором упоминается подбор ключей для них: habrahabr.ru/post/175557. Получается, вопрос здесь в считывателе и софте.

      Тогда уж сразу использовать Plus, пока про уязвимости их защиты не было слышно. Насчёт diy-реализаций не знаю, но с заводскими считывателями, работающими с ними корректно, сейчас негусто.


      1. Hellsy22
        24.02.2016 14:13

        Я довольно давно разбирался в вопросе, но все равно не понимаю при чем тут слабая криптозащита. Это в метро, в толкучке, можно незаметно перехватить поток данных между картой и ридером. А если около вашей двери будет крутиться какой-то подозрительный тип и прижиматься к вам — это наведет на некоторые подозрения.

        Что же до чистого удаленного взлома, то, если я правильно понял, в описанном в статье случае он идет за счет использования дефолтного ключа "А", ну, а если он не дефолтный — значит не повезло. Есть еще "dark side attack", но там время атаки вообще измеряется часами и работает не на всех картах. Это прокатит если вы сели в самолете недалеко от жертвы и можете неторопливо делать свое дело.

        А Ultralight клонируется мгновенно и без каких-либо сложностей.


        1. Axino
          25.02.2016 01:19

          Я имел ввиду как раз атаки на извлечение ключей от карты, к которой есть доступ — слабость криптозащиты и даёт такую возможность.
          Основной вопрос в том, что защищает система — если карты использовать, например, как ключи для дома — то здесь проще, поскольку ломать и некому особо. А вот с организацией можно обжечься, так как карты у сотрудников на руках, и ставший известным ключ превратит несколько часов в мгновенное считывание. По хорошему, сами ключи должны быть уникальными для разных карт, и это снимет риск кражи чужой карты — но для этого нужно иметь ввиду эту слабость (крипто)защиты и подобрать нормальное оборудование, так как часто ключ у считывателя один.

          Для удалённого считывания и перехвата трафика нужно нестандартное оборудование — тут дешевле искать другие способы. Хотя идея приёма радиосигнала интересна, сходу наработок не видно — может оказаться, что и смысла пытаться его принять нет. Так что хоть Ultralight, хоть Classic с известными ключами — прижаться придётся.

          В статье указан как раз подбор ключей, а вот утащить данные, не имея самой карты и не зная ключей — не попав под подозрение сложно.


          1. Hellsy22
            25.02.2016 04:08

            Да ладно, сейчас даже домофоны поддерживают уникальные ключи, не то, что серьезное оборудование.
            Но я еще раз отмечу: чтобы перехватить коммуникацию нужно находиться физически близко в тот момент, когда владелец карты ее использует. И это в перспективе позволит считать лишь блоки использовавшиеся в конкретный момент, а не всю карту целиком. Тогда как для полного считывания Ultralight достаточно просто пройти мимо человека с картой в кармане и "раскачанным" на 15см. ридером.