Advertisement
Manu-J

NFC-Reader

May 26th, 2024
470
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.02 KB | None | 0 0
  1. import sys
  2. import time
  3. import binascii
  4. from smartcard.System import readers
  5. from smartcard.util import toHexString
  6. from smartcard.Exceptions import NoCardException, CardConnectionException
  7. from rich.console import Console
  8. from rich.table import Table
  9. from rich.prompt import Prompt
  10. from rich import print
  11.  
  12. console = Console()
  13.  
  14. def select_reader():
  15.     reader_list = readers()
  16.     if not reader_list:
  17.         console.print("[red]No smart card readers found.[/red]")
  18.         sys.exit()
  19.  
  20.     console.print("[bold]Available readers:[/bold]")
  21.     for i, reader in enumerate(reader_list):
  22.         console.print(f"[green]{i}:[/green] {reader}")
  23.  
  24.     while True:
  25.         try:
  26.             reader_index = int(Prompt.ask("Select a reader", choices=[str(i) for i in range(len(reader_list))]))
  27.             return reader_list[reader_index]
  28.         except ValueError:
  29.             console.print("[red]Invalid input. Please enter a valid number.[/red]")
  30.  
  31. def connect_to_card(reader):
  32.     connection = reader.createConnection()
  33.     try:
  34.         connection.connect()
  35.         return connection
  36.     except NoCardException:
  37.         console.print("[red]No card detected. Please ensure the card is present and try again.[/red]")
  38.         return None
  39.     except CardConnectionException as e:
  40.         console.print(f"[red]Card connection error: {str(e)}[/red]")
  41.         return None
  42.  
  43. def get_uid(connection):
  44.     GET_UID_COMMAND = [0xFF, 0xCA, 0x00, 0x00, 0x00]
  45.     try:
  46.         data, sw1, sw2 = connection.transmit(GET_UID_COMMAND)
  47.         if sw1 == 0x90 and sw2 == 0x00:
  48.             return toHexString(data)
  49.         else:
  50.             return None
  51.     except CardConnectionException as e:
  52.         console.print(f"[red]Error during UID retrieval: {str(e)}[/red]")
  53.         return None
  54.  
  55. def read_data(connection, block_number):
  56.     READ_COMMAND = [0xFF, 0xB0, 0x00, block_number, 0x10]
  57.     try:
  58.         data, sw1, sw2 = connection.transmit(READ_COMMAND)
  59.         if sw1 == 0x90 and sw2 == 0x00:
  60.             return toHexString(data)
  61.         else:
  62.             console.print(f"[red]Failed to read block {block_number}: SW1={sw1:X}, SW2={sw2:X}[/red]")
  63.             return None
  64.     except CardConnectionException as e:
  65.         console.print(f"[red]Error during data read: {str(e)}[/red]")
  66.         return None
  67.  
  68. def write_data(connection, block_number, data):
  69.     if len(data) > 16:
  70.         console.print("[red]Data too long. Must be 16 bytes or less.[/red]")
  71.         return
  72.     data += [0x00] * (16 - len(data))  # Pad data to 16 bytes if necessary
  73.     WRITE_COMMAND = [0xFF, 0xD6, 0x00, block_number, 0x10] + data
  74.     try:
  75.         _, sw1, sw2 = connection.transmit(WRITE_COMMAND)
  76.         if sw1 == 0x90 and sw2 == 0x00:
  77.             console.print(f"[bold green]Successfully wrote data to block {block_number}.[/bold green]")
  78.         else:
  79.             console.print(f"[red]Failed to write block {block_number}: SW1={sw1:X}, SW2={sw2:X}[/red]")
  80.     except CardConnectionException as e:
  81.         console.print(f"[red]Error during data write: {str(e)}[/red]")
  82.  
  83. def scan_cards(reader):
  84.     console.print("[bold blue]Scanning for NFC cards... Press Ctrl+C to exit.[/bold blue]")
  85.     last_uid = None
  86.     while True:
  87.         try:
  88.             connection = reader.createConnection()
  89.             connection.connect()
  90.             uid = get_uid(connection)
  91.             if uid and uid != last_uid:
  92.                 console.print(f"[bold green]Detected NFC card with UID: {uid}[/bold green]")
  93.                 last_uid = uid
  94.                 # Perform desired actions with the detected card
  95.         except NoCardException:
  96.             pass
  97.         except CardConnectionException as e:
  98.             console.print(f"[red]Error during card scan: {str(e)}[/red]")
  99.         time.sleep(1)  # Delay to prevent rapid polling
  100.  
  101. def main():
  102.     reader = select_reader()
  103.    
  104.     while True:
  105.         console.print("\n[bold]Options:[/bold]")
  106.         console.print("[green]1.[/green] Scan NFC cards in real-time")
  107.         console.print("[green]2.[/green] Get UID of card")
  108.         console.print("[green]3.[/green] Read Data")
  109.         console.print("[green]4.[/green] Write Data")
  110.         console.print("[green]5.[/green] Exit")
  111.         choice = Prompt.ask("Select an option", choices=["1", "2", "3", "4", "5"])
  112.  
  113.         if choice == '1':
  114.             scan_cards(reader)
  115.         elif choice == '2':
  116.             connection = connect_to_card(reader)
  117.             if connection:
  118.                 uid = get_uid(connection)
  119.                 if uid:
  120.                     console.print(f"[bold green]UID:[/bold green] {uid}")
  121.                 else:
  122.                     console.print("[red]Failed to get UID.[/red]")
  123.         elif choice == '3':
  124.             connection = connect_to_card(reader)
  125.             if connection:
  126.                 block_number = Prompt.ask("Enter block number to read", default="0")
  127.                 try:
  128.                     block_number = int(block_number)
  129.                     data = read_data(connection, block_number)
  130.                     if data:
  131.                         console.print(f"[bold green]Data from block {block_number}:[/bold green] {data}")
  132.                 except ValueError:
  133.                     console.print("[red]Invalid block number. Please enter an integer.[/red]")
  134.         elif choice == '4':
  135.             connection = connect_to_card(reader)
  136.             if connection:
  137.                 block_number = Prompt.ask("Enter block number to write", default="0")
  138.                 try:
  139.                     block_number = int(block_number)
  140.                     data_hex = Prompt.ask("Enter data to write (in hex, e.g., 01 02 03 04)")
  141.                     data = [int(x, 16) for x in data_hex.split()]
  142.                     write_data(connection, block_number, data)
  143.                 except ValueError:
  144.                     console.print("[red]Invalid input. Please enter a valid block number and data in hex format.[/red]")
  145.         elif choice == '5':
  146.             break
  147.         else:
  148.             console.print("[red]Invalid option.[/red]")
  149.  
  150. if __name__ == "__main__":
  151.     main()
  152.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement