Utilisez READ BINARY pour lire plus de 256 octets

J’essaie de lire une carte à puce ( allemand Gesundheitskarte ) en utilisant javax.smartcardio

Dans la définition de l’EF “PD”, sa longueur est de 850 octets. Le contenu doit être une chaîne XML codée ISO5589-15 gzippée, comme spécifié ici.

En tant que CommandAPDU j’envoie

00 B0 00 00 00 

pour obtenir les 256 premiers octets. Après envoi

 00 B0 00 FF 00 

Je reçois les 256 prochains octets.

Mais comment puis-je obtenir le rest?

Comment saurai-je que les données binarys se terminent?

Spécifications allemandes, partie 1 | Spécifications allemandes partie 2

READ BINARY APDU READ BINARY autorisent 2 octets pour le décalage de fichier, codé en P1 et P2, et utilisent Le pour la longueur, pour READ BINARY le nombre d’octets dans la réponse. P1 est l’ octet de poids fort ou l’octet le plus significatif. Le bit le plus haut de P1 est toutefois réservé pour indiquer si P1 contient également un identificateur de fichier court . Il doit restr à la valeur 0 si vous lisez déjà un fichier, ce qui vous laisse un décalage maximum de 32Ki – 1.

Je ne peux pas lire les spécifications que vous avez liées, mais supposons que l’APDU READ BINARY sur votre carte fonctionne de la même manière.

Votre commande pour lire les 256 premiers octets semble correcte, notant que Le==0x00 indique une lecture pour 256 octets.

Pour lire les octets commençant aux décalages 256, 512, etc., commencez par incrémenter P1, par exemple:

 00 B0 01 00 00 00 B0 02 00 00 00 B0 03 00 00 

Pour lire 256 octets commençant au décalage 257 (0x101):

 00 B0 01 01 00 

Décalage 600 (0x258):

 00 B0 02 58 00 

Dans votre code, si vous utilisez Java int pour stocker le décalage, vous finirez généralement par incrémenter P1 avec quelque chose comme:

 int offset; int P1, P2; while (continueReading) { // ... P1 = (offset >> 8) & 0xFF; P2 = offset & 0x00FF; // ... // send APDU } 

La façon dont la taille d’un fichier est indiquée dépend de la mise en œuvre. En général, vous pouvez obtenir la taille du fichier à partir de la structure FCI (File Control Information) renvoyée par un SELECT sur l’EF ( 00 A4 00 00 02 fileId ). La taille du fichier peut toutefois aussi être intégrée au contenu du fichier. Si possible, ne vous fiez pas aux mots d’état pour vous dire la taille du fichier.


Addition: Le, Ne et INS impair

Il est important que vous n’augmentiez le décalage qu’avec la quantité d’octets que vous recevez réellement dans les données de réponse (RDATA). Notez que si P3 = Le, Le code code Ne, ce qui correspond à la taille maximale des données de réponse. Vous pouvez recevoir moins que cela.

Si la taille du fichier est égale ou supérieure à 32 Ko, vous devez utiliser READ BINARY avec un nombre impair INS ( B7 ) pour lire les données supérieures à 32 Ko. Dans ce cas, le RDATA peut également contenir des frais généraux. Évidemment, cela – à son tour – peut influencer les calculs de décalage et les calculs à lire jusqu’à la fin du fichier.

Le décalage est dans P1 & P2 , bien que le bit le plus élevé soit utilisé pour indiquer que vous voulez sélectionner quelque chose avec un SFI donné. Ainsi, vous pouvez également utiliser P1 pour les octets. Après cela, vous devrez vous diriger vers READ BINARY with an odd INS ( B1 ).

Ainsi, vous pouvez lire jusqu’à 2 ^ 15 – 1 octets en utilisant le binary en lecture normale. C’est 32Ki – 1. Et bien sûr, quelques octets supplémentaires à cause des octets renvoyés par l’APDU.

Je lisais toujours les fichiers des cartes à puce en appliquant la méthode suivante: 1 Déterminez la taille du fichier, par exemple, à l’aide de la FCI (Informations de contrôle de fichier) renvoyée avec un ID SELECT FILE ( 00 A4 02 00 02 ${FILE_ID} ). parsingr la réponse. Augmentez ensuite le décalage par le nombre d’ octets renvoyés à chaque fois. Ne demandez jamais plus que la taille maximale du fichier, car le comportement de la plupart des cartes diffère, n’est pas défini ou est simplement faux).

Sujet avancé: Si vous utilisez READ BINARY with ODD INS , vous devez soustraire l’en-tête du DO à chaque fois que vous augmentez le décalage. Dans ce cas, la lecture jusqu’à la fin devient un peu gênante car il faudrait append la surcharge de l’en-tête à l’octet Le .

Un petit ajout à la réponse très utile de Maarten Bodewes à propos de la lecture de fichiers plus volumineux et à la suggestion de stajo d’utiliser le fichier étendu. J’espère que cela économisera du temps et des efforts aux autres.

Essayer d’utiliser Le pour de longues lectures est délicat:

  • Extended Le nécessite également d’utiliser Extended Lc.
  • Extended Lc ne doit pas être 0, conformément à la norme, vous ne pouvez donc pas commencer avec le décalage 0
  • Et si votre Lc n’est pas égal à 0, vous devez utiliser l’INS “B1”.
  • Le B1 complique ensuite le calcul des tailles correctes, comme l’a expliqué Maarten Bodewes.

En plus de cela, vous devez d’abord savoir si la carte prend en charge le Lc / Le étendu. les informations à ce sujet sont réparties sur les octets d’historique d’ATR, l’EF.ATR et les informations actuelles sur l’EF.

Ainsi, s’il est théoriquement possible de lire de gros lots de données à partir d’un seul fichier, cela demande beaucoup d’efforts en pratique et vous ne pouvez pas non plus lire le fichier entier avec une seule commande.

Considérez ci-dessus avant de faire l’effort d’utiliser le Le étendu pour la lecture

Si la carte le prend en charge, vous pouvez probablement utiliser le format de longueur étendue. si vous spécifiez 00 dans le champ lc / le, vous pouvez utiliser deux octets suivants pour la longueur.