📜 ⬆️ ⬇️

Use Java smart cards to protect software. Chapter 2. Java smart card from the applet developer's point of view

image

In this series of articles we will discuss the use of Java smart cards (cheaper analog keys of electronic keys) to protect software. The cycle is divided into several chapters.

To read and understand the information from the articles you will need the following skills:

The purpose of the cycle is to acquaint the reader with Java maps (there is very little literature in Russian on their use). The cycle does not claim the status of "Guidelines for the development of software protection based on Java cards" or the title of "Handbook of Java cards."
')

The composition of the cycle:




1. APDU command.


The command passed to the applet is called the APDU command. The APDU command consists of five bytes of the header + data. However, the data itself can not be sent. Five bytes of the header:

For example:
00A4040008A000000003000000 

 [0x00] (CLA) [0xA4] (INS) [0x04] (P1) [0x00] (P2) [0x08] (LC) [0xA0 0x00 0x00 0x00 0x03 0x00 0x00 0x00] (DATA) 


0x00, 0xA4 is a SELECT APPLICATION command that selects an applet for later data exchange. To transfer a command to your applet, you must first select it with this command. The parameter P1 = 0x04 means that the applet is selected by its name (AID, see below). The parameter P2 = 0x00 means that we want to select an applet that strictly corresponds to the transferred name. As data (8 bytes), we passed the name of the applet ( "a000000003000000" is the standard name for the CardManager applet in some map variants). For details on the standard applet commands, see Global Platform Card Spec 2.1.1, p.105

As you can see, the maximum size of the command APDU is 255 + 5 = 260 bytes (there is, however, support for “long commands, but I have never used them). However, in practice, rarely use commands longer than a hundred bytes. I try to ensure that commands do not exceed 127 bytes in length. The reason for this precaution is simple: you may get cards whose APDU buffer size is less than 260 bytes and the long command simply will not accept the card. Have to send it in parts.

For their applets, it is better to choose the CLA value in the 0xD0-0xFE range, and the INS value is any that is not used by standard commands, except for the 0x60-0x6F, 0x90-0x9F ranges (this is a technical limitation of the T = 0 protocol).

2. AID. Packages


The name of the applet is called AID (Application Identifier). Several applets or simply classes can be combined into a package (in fact, the concept of a package with reference to Java cards is the same as in Java itself). The package also has an identifier (Package AID). The first bytes of the AID applet must be equal to the AID of its packet. For example, I have a package A0101010101010, and in it an applet with AID A010101010101055. The minimum length of an AID is 5 bytes. Maximum - 16.

3. Applet firewall. Communicating applets.


By default, applets are completely independent of each other. They have no way to transfer data to each other. However, one applet can implement the Shareable interface, giving others access to some of its methods. Only primitive data types and links to the APDU buffer can cross the border between applets (the place where the incoming command is usually placed in the card and the response to it is formed), since it is, in fact, common to all card applets.

Using the JavaCard API, various applets can talk to each other (using the Shareable interface). This allows, for example, to implement a permanent applet that returns the serial number of the card and a second applet that implements the set of functions you require. At the same time, the second applet can be safely updated, and the first one can be left on the map forever. Then he will be able to perform some operations dependent on the serial number (for example, to encrypt data uniquely for this serial number).

4. Return codes.


After running the command, the applet returns a two-byte result code. A successful result code may be accompanied by a set of response bytes. A list of possible return codes is here . Usually, the successful completion of the operation is 90 00 .

5. Work with memory.


All members of the applet class are located in the memory EEPROM of the card, which is rather slow. But usually cards have some small (up to several kilobytes) amount of transient memory, which is somewhat similar to RAM. Access to it is carried out several times faster. Such memory is allocated on request by calling JCSystem.makeTransientByteArray () . Please note that the amount of this memory is limited (the few kilobytes I mentioned are allocated to all card applets).

6. Data transfer protocols.


Two protocols are used to communicate with the cards - T = 0 and T = 1 . T = 0 is considered to be oriented on the transmission of characters, and T = 1 - oriented on the transmission of blocks of information. However, for us, these nuances do not matter. Simply speaking, these protocols differ only in that in the case of the T = 1 protocol, the data is transmitted by the stream, as we are used to (question-flow => flow-response), and in the case of T = 0, we have hemorrhoids with the need to form a command differently depending on whether we are transmitting data or not, whether we are waiting for data or not (details can be seen in the description of SCardTransmit . I will not consider the details of the protocols here (in due time they delivered me some hemorrhoids when the client suddenly had cards with T = 1, and my software worked only with T = 0), I note only that sim ilar to select components to work with maps that provide transparent support for both protocols. The interested differences I address my Delphi-component, which I use to communicate with the cards. I tried to embed a transparent support for both of them. As far as I got it, time will tell.

7. ATR and other card information


ATR = Answer To Reset is a set of bytes returned by the card for its identification. If it so happens that during the implementation of a certain project you had to use different types of cards, studying ATR is a good way to distinguish them. You can get ATR by calling SCardGetAttrib.

CPLC Data (Card Production Life Cycle Data) is a set of data about the card that CardManager applet normally returns when sending 0x80 0xCA 0x9F 0x7F commands to it. This data contains some system information about the card, such as, for example, the serial number of the EEPROM. I want to note that it is difficult to count on the uniqueness of, for example, the serial number of the EEPROM. If you intend to have a serial number on the card, write an applet that will read / write this number. Since I did not find the decoding of the CPLC Data fields in the official documentation, I quote the structure of this data in Delphi here:

  TFSCardAPICPLCData = packed record public CPLCTag: array[0..1] of Byte; // Expected: 9F 7F CPLCLength: Byte; // Expected: 2A IntegratedCircuitROMFabricator: array[0..1] of Byte; IntegratedCircuitROMType: array[0..1] of Byte; ROMOSidentifier: array[0..1] of Byte; OSReleaseDate: array[0..1] of Byte; OSReleaseLevel: array[0..1] of Byte; EEPROMFabricationDate: array[0..1] of Byte; EEPROMSerialNumber: array[0..3] of Byte; EEPROMBatchIdentifier: array[0..1] of Byte; EEPROMModuleFabricator: array[0..1] of Byte; EEPROMModulePackagingDate: array[0..1] of Byte; EEPROMIntegratedCircuitCardManufacturer: array[0..1] of Byte; EEPROMEmbeddingDate: array[0..1] of Byte; EEPROMPrePersonalizer: array[0..1] of Byte; EEPROMPrePersonalizationDate: array[0..1] of Byte; EEPROMPrePersonalizationEquipmentIdentifier: array[0..3] of Byte; EEPROMPersonalizer: array[0..1] of Byte; EEPROMPersonalizationDate: array[0..1] of Byte; EEPROMPersonalizationEquipmentIdentifier: array[0..3] of Byte; end; 

By the way, I came across cards that returned an error in response to a CPLC request. In fact, this means that the CPLC block was not registered in them during production.

8. Interception of data sent to / from the card


Since any software communicates with the card through the standard Windows libraries, always assume that any communication "there" and "back" can be intercepted. There are even special utilities for this, like APDUView . Therefore, all data exchange with the card must be encrypted. Which automatically assumes that your program must necessarily be protected by a protector such as Themida .

9. A little about performance


I conducted some tests with the cards that I had on hand. The test results are very approximate (I did not create any special conditions, the applet was used primitive). A 12Kb (kilobyte) data card (Gemalto TOP IM GX) can transfer in approximately 2.177 seconds. Encryption and transmission of 12Kb of 3DES2 data takes about 8.823 seconds, AES256 - 4.420 seconds.

It may seem that it is sparse. However, in this case, I always advise my clients to recall programming for the ZX Spectrum. So let the miracle happen on a few kilobytes.

10. Gratitude to patient readers.


Thanks to everyone who read to this place. Gratitude and indignation are accepted.

I will welcome any questions in the comments and try to update the article so that it includes the answers.

Source: https://habr.com/ru/post/255531/


All Articles