Analyse des nouveaux titres rechargeables des transports de Toulouse

Détail de la Création d'Adam : l'index de Dieu rejoint presque celui d'Adam qui tient un ticket de métro dans la main

Au mois de mars 2025, le réseau de transports Tisséo a introduit un nouveau support de titre de transport remplaçant l'ancien support magnétique. Les nouveaux tickets, similaires à vue d'œil, offrent deux avantages : ils ne se démagnétisent pas et permettent le rechargement plusieurs fois. Utilisatrice occasionnelle du réseau, j'en ai vite profité pour faire remplacer mon ancien carnet magnétique de 10 trajets qui avait arrêté de fonctionner au bout de 5 validations par un ticket rechargeable.

Contrairement à la RATP/IDFM qui a vraisemblablement réutilisé la technologie Calypso des pass Navigo pour les supports Navigo Easy le réseau Tisséo comme d'autres villes en France a choisi une solution moins chère avec ces tickets en carton : ils sont vendus au prix de 20 centimes en plus du prix des titres. Les cartes Navigo Easy sont elles vendues 2€ à Paris. L'inconvénient du ticket en carton, en plus de sa relative fragilité matérielle, est le nombre limité de recharges : Tisséo indique plus de 30 fois !

La (relative) simplicité technique de ces nouveaux tickets en fait un excellent cas d'exemple pédagodique du fonctionnement du NFC ! Cette page va surtout se concentrer sur la manière dont sont codées les données et comment leur intégrité en est assurée.

Les données d'un tag ST25TB

Chaque titre en carton contient un tag NFC ST25TB de STMicroelectronics d'une capacité de 512 bits. La mémoire est divisée en 16 blocs de 32 bits sur lesquels l'écriture est libre à une subtilité près.

Trois blocs supplémentaires sont présents :

Tous les blocs sont par défaut accessibles en lecture et écriture et le tag ne contient aucun mécanisme de contrôle d'accès. Toutefois les blocs 5 et 6 sont spéciaux, ce sont des compteurs de décrémentation : ils sont initialisés avec les valeurs FF FF FF FF et ne peuvent être mis à jour qu'avec une valeur inférieure.

Toute la sécurité anti-fraude de ces supports repose sur trois choses :

Arrière d'un ticket avec le numéro de série
Arrière d'un ticket

Structure d'un ticket

Pour rendre la lecture plus claire j'ai mis les octets de poids fort côté gauche.

    0: 61 40 20 30   Système et distribution
    1: 25 09 16 24   Distribution
    2: 04 1F 6A C4   Distribution
    3: FA A2 28 08   Usage A
    4: CC F3 83 E9   Usage A
    5: FE 00 00 09   Compteur 1
    6: FF FF FF FC   Compteur 2
    7: 00 05 E0 FA   Usage A
    8: C0 00 18 43   Usage A
    9: C4 12 B6 AF   Usage A
   10: FA A1 08 08   Usage B
   11: C2 F3 83 EB   Usage B
   12: 00 00 A0 00   Usage B
   13: 00 00 18 43   Usage B
   14: C4 00 CE 3F   Usage B
   15: 91 B5 61 9F   Signature
  OTP: FF FF FF FF   Bloc OTP
UID 0: D0 02 33 7F   Première partie de l'UID
UID 1: 6F 2D 0E 69   Deuxième partie de l'UID

Le choix de réserver 5 blocs par usage en sacrifiant la taille des données de distribution est un choix de Tisséo, d'autres partitionnements sont possibles et décrits dans la norme.

Extraction et interprétation des données

Norme Intertic

Ces titres de transports sont encodés à la norme Intertic, plus précisément :

Intertic est la version « allégée » d'Intercode, une autre norme prévue pour les cartes d'abonnement qui possèdent plus de mémoire. Il existe aussi Interbob pour normaliser les échanges entre les systèmes informatiques et Transmodel pour les bases de données.

Le formatage des données sur un titre peut être complexe parce qu'Intertic est très flexible et peut s'adapter aux règles de différents réseaux de transports. Les données sont inscrites sur chaque titre de manière séquentielle mais entre ces données il arrive que des champs spéciaux indiquent quelles données optionnelles sont présentes ou absentes. Heureusement la quantité de mémoire très réduite du titre rechargeable impose une certaine simplicité. En réalité pour les titres rechargeables Tisséo, à une exception près, les données sont situées à des emplacements fixes ce qui les rend faciles à décoder.

Système et distribution

Pour extraire les informations générales d'un titre, il faut lier les blocs 1, 2 et 0 dans cet ordre puis les découper :

Bloc 1 : 001001010000 100100010110 001001 00
         A            B            C      D...

Bloc 2 : 000001 0000011111011010 1011000100
                E                F...

Bloc 0 : 0110 00010 10 00000001 0000 0001 10000
              G     H  I        J    K    L
Lettre Taille (bits) Signification Valeur
A 12 Code pays 0x250 (France)
B 12 Autorité organisatrice 0x916 (Tisséo)
C 6 Version de contrat 9
D 8 Fournisseur de contrat 1
E 16 Tarif de contrat 2010
F 14 Date de fin de contrat 2028-01-05
G 5 Définit le formatage
H 2 Définit le formatage
I 8 Exploitant 1
J 4 Vide
K 4 ID du jeu de clés (système) 1
L 5 ID de partition (système) 0x10
Écran affichant 0 titres disponibles, impossible à recharger car plein
Le ticket qui m'a été échangé contre l'ancien magnétique a été chargé avec des « déplacements SAV », je ne peux pas le recharger*
Écran affichant 10 titres disponibles, rechargeable par 10 uniquement
Nouveau ticket rechargeable avec 10 titres disponibles, dumpé ici en exemple, je ne peux ajouter que des titres similaires (des lots de 10)

Normalement je suis supposée pouvoir charger le type de titre que je souhaite une fois que la carte est vide, j'ai tendance à penser que le bug qui m'empêche de recharger ma première carte est causé par le type de titre non disponible à l'achat (déplacement SAV, tarif 2060).

Usages

Découpage du usage B pour l'exemple, c'est pareil pour le A :

Bloc 10 : 1111101010 10000100001 00000001 000
          A          B           C        D...

Bloc 11 : 11  00001 01111 001110 00001111101011
              E     F     G      H

Bloc 12 : 00 0000000000000010 10 000000000000
          I  J                K  L...

Bloc 13 : 00 00000000000000 0001 10000100001 1
             M              N    O           P...

Bloc 14 : 11 0001 000000 000 0 1100111000111111
             Q    R      S     Signature
Lettre Taille Signification Valeur usage B Valeur usage A
A 10 Date de validation 2025-04-16 2025-04-16
B 11 Heure de validation 17:37 18:13
C 8 Exploitant 1 1
D 5 Nature 3 (métro) 3 (métro)
E 5 Type de validation 1 (validation entrée) 6 (correspondance)
F 5 Définit le formatage
G 6 Définit le formatage
H 14 ID de ligne 1003 (ligne C) 1001 (ligne A)
I 2 Direction - -
J 16 Code station (optionnel) 2 23
K 2 Définit le formatage
L 14 ID de ligne précédente - 1003 (ligne C)
M 14 ID de ligne encore précédente - -
N 4 Définit le formatage
O 11 Heure de 1e validation 17:37 17:37
P 3 Définit le formatage
Q 4 Nombre de passagers 1 1
R 6 Nombre de trajets 1 0
S 3 Nombre de correspondances 1 0

Identifiants internes

Le tableau suivant référence les différents codes station que j'ai repérés au fil du temps. Le réseau de Toulouse est un des rares (le seul ?) ou on valide en correspondance dans le métro, ce qui permet au valideur de toujours connaître la ligne empruntée. Je ne vois pas de lien avec les données GTFS disponibles en open data, ce sont des identifiants internes. J'ai l'impression que les stations sont par ordre alphabétique ?

ID Ligne Station
1 C Arènes (gare)
2 C Colomiers (gare)
23 A Arènes
29 A Capitole
31 A Esquirol
33 A Jean Jaurès
36 A Marengo SNCF
43 A Saint-Cyprien
46 B Canal du Midi
51 B Jeanne d'Arc
53 B Jean Jaurès (depuis la A)
54 B Jean Jaurès (depuis l'extérieur)
55 B La Vache
57 B Palais de justice
59 B Ramonville
64 B Saint-Michel
65 B Trois Cocus
83 Téléo Université Paul Sabatier

Ce tableau référence l'ID de chaque ligne dans le système, là encore ça ne correspond pas aux données GTFS. Pour les autobus, c'est juste le numéro de la ligne de bus.

ID Nom commercial de la ligne
24 Bus aéroport
835 Bus relai métro B
1001 Métro A
1002 Métro B
1003 Train Arènes-Colomiers (ex ligne C)
1005 Tramway T1
1007 Câble Téléo

Ce tableau référence les ID correspondant aux tarifs, c'est à dire les différents types de tickets qu'on peut charger sur un titre rechargeable. La liste n'est pas exhaustive, il m'en manque quelques uns.

ID Type de billet
2005 1 déplacement
2007 1 déplacement dernière minute (à bord)
2010 10 déplacements
2020 2 déplacements
2060 1 déplacement (SAV)
2090 1 déplacement aéroport (à bord)

Sécurité du support

La décrémentation du bloc 5 de manière similaire à un automate est possible mais invalide la signature du bloc 15 et rend le titre illégitime.

On pourrait penser que changer l'horodatage du dernier usage pour simuler une correspondance pourrait éviter la décrémentation d'un titre lors de la validation mais chaque usage est protégé par sa propre signature.

Impossible aussi d'escalader de tarif par exemple en achetant un titre « 1 déplacement » et en le transformant en ticket aéroport parce que son authenticité est protégée par la signature du bloc 15.

Il reste l'hypothèse de remonter dans le temps en réinitialisant le ticket dans un état passé. Ça nécessite d'incrémenter le compteur 5, c'est normalement matériellement impossible mais les tags ST25TB sont sensibles aux attaques par arrachage, ça a fait l'objet de recherches depuis plusieurs années et les réseaux de transport sont supposés être informés.

Dans leur note technique TN1530 de mai 2024 STMicroelectronics conseille :

Follow the recommendations provided in section Antitearing protection of “Best practices for security and privacy with ST25 NFC/ RFID Tags” (AN5493)

Ça nous mène à la note d'application AN5493 qui nous met déjà dans l'ambiance dès la page 2 :

ST25 NFC /RFID Tags devices are not certified products that can be used in entry level security applications. In case of needs of a more secure solution as in the transportation domain, for example, STMicroelectronics can propose the CD21 product portfolio using the certified secure ST31 IC family and compliant with all Calypso requirements.

Après nous avoir présenté les diverses fonctionnalités de différents tags de la série ST25 le même document - mis à jour en mai 2025 - nous précise dans la section 5.2.3.4 Antitearing protection (p. 28) :

It may not be sufficient in the applications that are often faced daily human threats and risks such as fraud. Certain enhanced attacks to cause an impact on the security automatic mechanism and to exploit vulnerability may occur and need to be thwarted by combining technical controls since ST25 series are not considered as security certified products and may not resist to advanced attacks.

C'est quand même abusé pour un système vendu spécifiquement pour les transports.

Extrait de diaporama qui présente le produit comme conçu pour le transport
ST25TB product presentation, mai 2020 [pdf]
Page qui précise Application : transport
Première page du datasheet, février 2023 [pdf]

Enfin toujours dans la même section le document suggère quelques stratégies : utiliser des checksums pour assurer l'intégrité des données (oui mais quel rapport avec mon potiron ?), utiliser des signatures (déjà fait) ou faire des vérifications côté serveur, ce qui est probablement la seule stratégie viable à terme mais techniquement très compliqué pour un réseau de transports.

Photo de Jean-Pierre Coffe

Pour conclure, Tisséo utilise la norme Intertic de manière optimale pour assurer le respect des contraintes de la tarification dans la mémoire réduite du ST25TB512 mais cette technologie n'offre pas un niveau de sécurité adapté à l'usage qui en est fait. Les cartes Pastel utilisées pour les abonnements permettant déjà de charger des titres unitaires, en vendre des non-nominatives comme fait IDFM avec le Navigo Easy ou les réseaux de transport du Québec avec la carte Opus aurait garanti un meilleur niveau de sécurité malgré un coût du support plus élevé. Les nombreux réseaux de transports en France qui utilisent le ST25TB s'exposent aux mêmes problèmes.

Pour en apprendre plus