Stadium Ticketing Research
This research explores a secure ticketing system that leverages RSA cryptography and Redis for real-time verification. It prevents ticket fraud using a rotating barcode mechanism.
System Overview
The ticketing system consists of a Flask web server, a Redis database, and a frontend built with Angular. It generates, verifies, and manages digital tickets securely.
Key Features
- RSA key generation and management for cryptographic security
- Rotating QR codes to prevent ticket reuse and fraud
- Redis-backed real-time ticket validation
- Frontend integration with Angular and a QR code scanner
Implementation Details
RSA Key Management
The system generates an RSA key pair for signing and verifying tickets. Keys are stored in PEM format.
QR Code Generation
1
2def generate_barcode(ticket_id: str, private_key):
3 timestamp = int(time.time() // 30)
4 barcode_data = json.dumps({"i": ticket_id, "t": timestamp})
5 signature = private_key.sign(
6 barcode_data.encode(),
7 padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=32),
8 hashes.SHA256()
9 )
10 barcode_payload = base64.b32encode(barcode_data.encode()).decode()
11 signature_payload = base64.b32encode(signature).decode()
12 barcode_final = json.dumps({"d": barcode_payload, "s": signature_payload})
13 print(f"Generated barcode: {barcode_final}")
14 qr = qrcode.QRCode(version=1, error_correction=qrcode.constants.ERROR_CORRECT_L, box_size=10, border=4)
15 qr.add_data(barcode_final)
16 qr.make(fit=True)
17 img = qr.make_image(fill='black', back_color='white')
18 buffer = BytesIO()
19 img.save(buffer, format='PNG')
20 buffer.seek(0)
21 return buffer
The function generate_barcode takes a ticket ID and a private key to create a secure QR code image that encodes ticket information. It constructs a JSON string containing the ticket ID and timestamp, signs it using RSA-PSS with SHA-256, and encodes the resulting data to produce the final payload used for QR code generation.
Real-time Verification
When a ticket is scanned, the system checks Redis to ensure it has not been previously used. If valid, access is granted; otherwise, an error is displayed.