Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import sys
- import time
- import binascii
- from smartcard.System import readers
- from smartcard.util import toHexString
- from smartcard.Exceptions import NoCardException, CardConnectionException
- from rich.console import Console
- from rich.table import Table
- from rich.prompt import Prompt
- from rich import print
- console = Console()
- def select_reader():
- reader_list = readers()
- if not reader_list:
- console.print("[red]No smart card readers found.[/red]")
- sys.exit()
- console.print("[bold]Available readers:[/bold]")
- for i, reader in enumerate(reader_list):
- console.print(f"[green]{i}:[/green] {reader}")
- while True:
- try:
- reader_index = int(Prompt.ask("Select a reader", choices=[str(i) for i in range(len(reader_list))]))
- return reader_list[reader_index]
- except ValueError:
- console.print("[red]Invalid input. Please enter a valid number.[/red]")
- def connect_to_card(reader):
- connection = reader.createConnection()
- try:
- connection.connect()
- return connection
- except NoCardException:
- console.print("[red]No card detected. Please ensure the card is present and try again.[/red]")
- return None
- except CardConnectionException as e:
- console.print(f"[red]Card connection error: {str(e)}[/red]")
- return None
- def get_uid(connection):
- GET_UID_COMMAND = [0xFF, 0xCA, 0x00, 0x00, 0x00]
- try:
- data, sw1, sw2 = connection.transmit(GET_UID_COMMAND)
- if sw1 == 0x90 and sw2 == 0x00:
- return toHexString(data)
- else:
- return None
- except CardConnectionException as e:
- console.print(f"[red]Error during UID retrieval: {str(e)}[/red]")
- return None
- def read_data(connection, block_number):
- READ_COMMAND = [0xFF, 0xB0, 0x00, block_number, 0x10]
- try:
- data, sw1, sw2 = connection.transmit(READ_COMMAND)
- if sw1 == 0x90 and sw2 == 0x00:
- return toHexString(data)
- else:
- console.print(f"[red]Failed to read block {block_number}: SW1={sw1:X}, SW2={sw2:X}[/red]")
- return None
- except CardConnectionException as e:
- console.print(f"[red]Error during data read: {str(e)}[/red]")
- return None
- def write_data(connection, block_number, data):
- if len(data) > 16:
- console.print("[red]Data too long. Must be 16 bytes or less.[/red]")
- return
- data += [0x00] * (16 - len(data)) # Pad data to 16 bytes if necessary
- WRITE_COMMAND = [0xFF, 0xD6, 0x00, block_number, 0x10] + data
- try:
- _, sw1, sw2 = connection.transmit(WRITE_COMMAND)
- if sw1 == 0x90 and sw2 == 0x00:
- console.print(f"[bold green]Successfully wrote data to block {block_number}.[/bold green]")
- else:
- console.print(f"[red]Failed to write block {block_number}: SW1={sw1:X}, SW2={sw2:X}[/red]")
- except CardConnectionException as e:
- console.print(f"[red]Error during data write: {str(e)}[/red]")
- def scan_cards(reader):
- console.print("[bold blue]Scanning for NFC cards... Press Ctrl+C to exit.[/bold blue]")
- last_uid = None
- while True:
- try:
- connection = reader.createConnection()
- connection.connect()
- uid = get_uid(connection)
- if uid and uid != last_uid:
- console.print(f"[bold green]Detected NFC card with UID: {uid}[/bold green]")
- last_uid = uid
- # Perform desired actions with the detected card
- except NoCardException:
- pass
- except CardConnectionException as e:
- console.print(f"[red]Error during card scan: {str(e)}[/red]")
- time.sleep(1) # Delay to prevent rapid polling
- def main():
- reader = select_reader()
- while True:
- console.print("\n[bold]Options:[/bold]")
- console.print("[green]1.[/green] Scan NFC cards in real-time")
- console.print("[green]2.[/green] Get UID of card")
- console.print("[green]3.[/green] Read Data")
- console.print("[green]4.[/green] Write Data")
- console.print("[green]5.[/green] Exit")
- choice = Prompt.ask("Select an option", choices=["1", "2", "3", "4", "5"])
- if choice == '1':
- scan_cards(reader)
- elif choice == '2':
- connection = connect_to_card(reader)
- if connection:
- uid = get_uid(connection)
- if uid:
- console.print(f"[bold green]UID:[/bold green] {uid}")
- else:
- console.print("[red]Failed to get UID.[/red]")
- elif choice == '3':
- connection = connect_to_card(reader)
- if connection:
- block_number = Prompt.ask("Enter block number to read", default="0")
- try:
- block_number = int(block_number)
- data = read_data(connection, block_number)
- if data:
- console.print(f"[bold green]Data from block {block_number}:[/bold green] {data}")
- except ValueError:
- console.print("[red]Invalid block number. Please enter an integer.[/red]")
- elif choice == '4':
- connection = connect_to_card(reader)
- if connection:
- block_number = Prompt.ask("Enter block number to write", default="0")
- try:
- block_number = int(block_number)
- data_hex = Prompt.ask("Enter data to write (in hex, e.g., 01 02 03 04)")
- data = [int(x, 16) for x in data_hex.split()]
- write_data(connection, block_number, data)
- except ValueError:
- console.print("[red]Invalid input. Please enter a valid block number and data in hex format.[/red]")
- elif choice == '5':
- break
- else:
- console.print("[red]Invalid option.[/red]")
- if __name__ == "__main__":
- main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement