com.datecs.emsr

## Class EMSR

- java.lang.Object
- - com.datecs.emsr.EMSR

-     public class EMSR
      extends java.lang.Object

- - ### Nested Class Summary

    Nested Classes
    Modifier and Type | Class and Description
    --- | ---
    `static class` | `EMSR.EMSRInformation` The class that contains various information about encrypted magnetic stripe reader (EMSR).
    `static class` | `EMSR.EMSRKeyInformation` The class that contains various information about encrypted magnetic stripe reader (EMSR).

  - ### Field Summary

    Fields
    Modifier and Type | Field and Description
    --- | ---
    `static int` | `ENCRYPTION_TYPE_AES256` Encrypted Magnetic Head AES 256 encryption algorithm After decryption, the result data will be as follows: Random data (4 bytes).
    `static int` | `ENCRYPTION_TYPE_IDTECH` Encrypted Magnetic Head IDTECH encryption algorithm, please refer to IDTECH documentation for detailed format and examples.
    `static int` | `ENCRYPTION_TYPE_OLD_RSA` Card data will be sent encrypted in the format: Encryption type (1 byte): 01 - RSA2048 encrypted.
    `static int` | `ENCRYPTION_TYPE_RSA` Card data will be sent encrypted in the format: Encryption type (1 byte): 01 - RSA2048 encrypted.
    `static int` | `KEY_AES_AUTHENTICATION`
    `static int` | `KEY_AES_DATA_ENCRYPTION` Encryption key, if set magnetic card data will be encrypted.
    `static int` | `KEY_AES_KEK` Encrypted head key loading key.
    `static int` | `KEY_DUKPT_MASTER` Encrypted head DUKPT master key.
    `static int` | `KEY_NO_KEY` No key.
    `static int` | `KEY_TMK_AES` Encrypted head TMK key.
    `static int` | `MODE_READ_JIS` Read JIS card.
    `static int` | `MODE_READ_PREFIX` Read data with prefix before tracks - 0xF0, 0xF1, 0xF2.
    `static int` | `MODE_READ_RAW` Read raw data.
    `static int` | `MODE_READ_TRACK1` Read track 1.
    `static int` | `MODE_READ_TRACK2` Read track 2.
    `static int` | `MODE_READ_TRACK3` Read track 3.
    `static int` | `STATUS_EMSR_BAD_ARRAY`
    `static int` | `STATUS_EMSR_BARCODE_MISHMASH`
    `static int` | `STATUS_EMSR_BARCODE_NO_READER`
    `static int` | `STATUS_EMSR_CARD_ERROR`
    `static int` | `STATUS_EMSR_HARD`
    `static int` | `STATUS_EMSR_INVALID_COMMAND`
    `static int` | `STATUS_EMSR_INVALID_LENGTH`
    `static int` | `STATUS_EMSR_INVALID_SIGNATURE`
    `static int` | `STATUS_EMSR_NO_BARCODE_READ`
    `static int` | `STATUS_EMSR_NO_DATA`
    `static int` | `STATUS_EMSR_NO_PERMISSION`
    `static int` | `STATUS_EMSR_NO_RESPONSE`
    `static int` | `STATUS_EMSR_SYNTAX_ERROR`
    `static int` | `STATUS_EMSR_TAMPERED`

  - ### Constructor Summary

    Constructors
    Constructor and Description
    `EMSR(java.io.InputStream in, java.io.OutputStream out)` Constructs a new instance of this class from a given `InputStream` and `OutputStream`.

  - ### Method Summary

    All Methods Static Methods Instance Methods Concrete Methods
    Modifier and Type | Method and Description
    --- | ---
    `void` | `close()` Close the streams and release all associated resources.
    `void` | `disable()` Disable encrypted magnetic stripe reader (EMSR).
    `void` | `enable()` Enable encrypted magnetic stripe reader (EMSR).
    `EMSR.EMSRInformation` | `getInformation()` Returns information about encrypted magnetic stripe reader (EMSR).
    `EMSR.EMSRKeyInformation` | `getKeyInformation(int keyId)` Returns information about keys into encrypted magnetic stripe reader (EMSR).
    `void` | `loadKey(byte[] keyData)` Loads new key, in plain or encrypted with already loaded AES256 Key Encryption Key (KEK).
    `byte[]` | `readCardData(int mode)` Read card data.
    `static void` | `setDebug(boolean on)` Specify whether the object can output debug information
    `void` | `setEncryptionType(int type)` Set encryption type.
    `int` | `test(int ms)` Test encrypted magnetic head.
    `byte[]` | `transmitEMSR(byte[] input)` Transmit data to encrypted magnetic stripe reader (EMSR).

    - ### Methods inherited from class java.lang.Object

      `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- - ### Field Detail

    - #### STATUS_EMSR_INVALID_COMMAND

          public static final int STATUS_EMSR_INVALID_COMMAND

      See Also:
        Constant Field Values

    - #### STATUS_EMSR_NO_PERMISSION

          public static final int STATUS_EMSR_NO_PERMISSION

      See Also:
        Constant Field Values

    - #### STATUS_EMSR_CARD_ERROR

          public static final int STATUS_EMSR_CARD_ERROR

      See Also:
        Constant Field Values

    - #### STATUS_EMSR_SYNTAX_ERROR

          public static final int STATUS_EMSR_SYNTAX_ERROR

      See Also:
        Constant Field Values

    - #### STATUS_EMSR_NO_RESPONSE

          public static final int STATUS_EMSR_NO_RESPONSE

      See Also:
        Constant Field Values

    - #### STATUS_EMSR_NO_DATA

          public static final int STATUS_EMSR_NO_DATA

      See Also:
        Constant Field Values

    - #### STATUS_EMSR_BAD_ARRAY

          public static final int STATUS_EMSR_BAD_ARRAY

      See Also:
        Constant Field Values

    - #### STATUS_EMSR_NO_BARCODE_READ

          public static final int STATUS_EMSR_NO_BARCODE_READ

      See Also:
        Constant Field Values

    - #### STATUS_EMSR_BARCODE_MISHMASH

          public static final int STATUS_EMSR_BARCODE_MISHMASH

      See Also:
        Constant Field Values

    - #### STATUS_EMSR_BARCODE_NO_READER

          public static final int STATUS_EMSR_BARCODE_NO_READER

      See Also:
        Constant Field Values

    - #### STATUS_EMSR_INVALID_LENGTH

          public static final int STATUS_EMSR_INVALID_LENGTH

      See Also:
        Constant Field Values

    - #### STATUS_EMSR_TAMPERED

          public static final int STATUS_EMSR_TAMPERED

      See Also:
        Constant Field Values

    - #### STATUS_EMSR_INVALID_SIGNATURE

          public static final int STATUS_EMSR_INVALID_SIGNATURE

      See Also:
        Constant Field Values

    - #### STATUS_EMSR_HARD

          public static final int STATUS_EMSR_HARD

      See Also:
        Constant Field Values

    - #### KEY_AES_AUTHENTICATION

          public static final int KEY_AES_AUTHENTICATION

      See Also:
        Constant Field Values

    - #### KEY_AES_DATA_ENCRYPTION

          public static final int KEY_AES_DATA_ENCRYPTION

      Encryption key, if set magnetic card data will be encrypted.
      See Also:
        Constant Field Values

    - #### KEY_AES_KEK

          public static final int KEY_AES_KEK

      Encrypted head key loading key.
      See Also:
        Constant Field Values

    - #### KEY_TMK_AES

          public static final int KEY_TMK_AES

      Encrypted head TMK key.
      See Also:
        Constant Field Values

    - #### KEY_DUKPT_MASTER

          public static final int KEY_DUKPT_MASTER

      Encrypted head DUKPT master key.
      See Also:
        Constant Field Values

    - #### KEY_NO_KEY

          public static final int KEY_NO_KEY

      No key.
      See Also:
        Constant Field Values

    - #### ENCRYPTION_TYPE_OLD_RSA

          public static final int ENCRYPTION_TYPE_OLD_RSA

      Card data will be sent encrypted in the format:
      - Encryption type (1 byte): 01 - RSA2048 encrypted.
      - RSA key block in PKCS1 format (256 bytes).
      - Device unique serial number (13 bytes, string).
      - Padding (3 bytes).
      - Random data (4 bytes).
      - Track 2 data, 00 terminated.
      - Cardholder name, 00 terminated.
      - SHA256 on all the data starting with the serial number, padding, random data, track 2 data and cardholder name.
      - Padding data - bytes with value 00.

      Random data, track 2 data, cardholder name, sha256 and the padding are encrypted with AES128.

      See Also:
        Constant Field Values

    - #### ENCRYPTION_TYPE_RSA

          public static final int ENCRYPTION_TYPE_RSA

      Card data will be sent encrypted in the format:
      - Encryption type (1 byte): 01 - RSA2048 encrypted.
      - RSA key block in PKCS1 format (256 bytes).
      - Device unique serial number (13 bytes, string).
      - Padding (3 bytes).
      - Random data (4 bytes).
      - Track 2 data, 00 terminated.
      - Cardholder name, 00 terminated.
      - SHA256 on all the data starting with the serial number, padding, random data, track 2 data and cardholder name.
      - Padding data - bytes with value 00.

      Random data, track 2 data, cardholder name, sha256 and the padding are encrypted with AES128.

      See Also:
        Constant Field Values

    - #### ENCRYPTION_TYPE_AES256

          public static final int ENCRYPTION_TYPE_AES256

      Encrypted Magnetic Head AES 256 encryption algorithm After decryption, the result data will be as follows:
      - Random data (4 bytes).
      - Device identification text (16 ASCII characters, unused bytes are 0).
      - Processed track data in the format: 0xF1 (track1 data), 0xF2 (track2 data) 0xF3 (track3 data). It is possible some of the tracks will be empty, then the identifier will not be present too, for example 0xF1 (track1 data) 0xF3 (track3 data).
      - End of track data (byte 0x00).
      - CRC16CCIT (2 bytes) - the CRC is performed from the start of the encrypted block (the Random Data block) to the end of the track data (including the 0x00 byte).
      The data block is rounded to 16 bytes.
      See Also:
        Constant Field Values

    - #### ENCRYPTION_TYPE_IDTECH

          public static final int ENCRYPTION_TYPE_IDTECH

      Encrypted Magnetic Head IDTECH encryption algorithm, please refer to IDTECH documentation for detailed format and examples. Data, that is received via magneticCardEncryptedData has the following format:
      - (1 byte) card encoding type, can ignore.
      - (1 byte) bits marking which track is present.
      - (1 byte) track 1 UNENCRYPTED length.
      - (1 byte) track 2 UNENCRYPTED length.
      - (1 byte) track 3 UNENCRYPTED length.
      - (track 1 UNENCRYPTED length bytes) track 1 masked data.
      - (track 2 UNENCRYPTED length bytes) track 2 masked data.
      - (track 3 UNENCRYPTED length bytes) track 3 masked data.
      - (variable bytes) Track 1 + Track 2 encrypted data, the length of this block is calculated by subtracting from the end.
      - (20 bytes) track 1 sha1.
      - (20 bytes) track 2 sha1.
      - (10 bytes) KSN.
      Encrypted block contents after decryption (3DES):
      - track 1 UNENCRYPTED length bytes) track 1 data.
      - (track 2 UNENCRYPTED length bytes) track 2 data.
      See Also:
        Constant Field Values

    - #### MODE_READ_TRACK1

          public static final int MODE_READ_TRACK1

      Read track 1.
      See Also:
        Constant Field Values

    - #### MODE_READ_TRACK2

          public static final int MODE_READ_TRACK2

      Read track 2.
      See Also:
        Constant Field Values

    - #### MODE_READ_TRACK3

          public static final int MODE_READ_TRACK3

      Read track 3.
      See Also:
        Constant Field Values

    - #### MODE_READ_JIS

          public static final int MODE_READ_JIS

      Read JIS card.
      See Also:
        Constant Field Values

    - #### MODE_READ_RAW

          public static final int MODE_READ_RAW

      Read raw data.
      See Also:
        Constant Field Values

    - #### MODE_READ_PREFIX

          public static final int MODE_READ_PREFIX

      Read data with prefix before tracks - 0xF0, 0xF1, 0xF2.
      See Also:
        Constant Field Values

  - ### Constructor Detail

    - #### EMSR

          public EMSR(java.io.InputStream in,
                      java.io.OutputStream out)
               throws java.io.IOException

      Constructs a new instance of this class from a given `InputStream` and `OutputStream`.
      Parameters:
        `in` - the input stream.
        `out` - the output stream.
      Throws:
        `java.io.IOException` - if an I/O error occurs.

  - ### Method Detail

    - #### close

          public void close()

      Close the streams and release all associated resources.

    - #### setDebug

          public static void setDebug(boolean on)

      Specify whether the object can output debug information
      Parameters:
        `on` - True to enable debbuging; otherwise false.

    - #### transmitEMSR

          public byte[] transmitEMSR(byte[] input)
                              throws java.io.IOException

      Transmit data to encrypted magnetic stripe reader (EMSR).
      Parameters:
        `input` - the input data to process.
      Returns:
        the result of data processing.
      Throws:
        `java.io.IOException` - if an I/O error occurs.

    - #### enable

          public void enable()
                      throws EMSRException,
                             java.io.IOException

      Enable encrypted magnetic stripe reader (EMSR).
      Throws:
        `EMSRException` - if a reader error occurs.
        `java.io.IOException` - if an I/O error occurs.

    - #### disable

          public void disable()
                       throws EMSRException,
                              java.io.IOException

      Disable encrypted magnetic stripe reader (EMSR).
      Throws:
        `EMSRException` - if a reader error occurs.
        `java.io.IOException` - if an I/O error occurs.

    - #### getInformation

          public EMSR.EMSRInformation getInformation()
                                              throws EMSRException,
                                                     java.io.IOException

      Returns information about encrypted magnetic stripe reader (EMSR).
      Returns:
        information about EMSR.
      Throws:
        `EMSRException` - if a reader error occurs.
        `java.io.IOException` - if an I/O error occurs.

    - #### getKeyInformation

          public EMSR.EMSRKeyInformation getKeyInformation(int keyId)
                                                    throws EMSRException,
                                                           java.io.IOException

      Returns information about keys into encrypted magnetic stripe reader (EMSR).
      Parameters:
        `keyId` - the ID of the key to get the version, one of the KEY_* constants definition.
      Returns:
        the key information.
      Throws:
        `EMSRException` - if a reader error occurs.
        `java.io.IOException` - if an I/O error occurs.

    - #### loadKey

          public void loadKey(byte[] keyData)
                       throws EMSRException,
                              java.io.IOException

      Loads new key, in plain or encrypted with already loaded AES256 Key Encryption Key (KEK). Plain text loading works only the first time the specified key is loaded and is recommended only in secure environment. For normal usage the new key should be encrypted with the Key Encryption Key (KEK). The command is unavailable if the device is tampered.
      Parameters:
        `keyData` - a byte array, that consists of:
        - MAGIC NUMBER - (1 byte) 0x2b
        - ENCRYPTION KEY ID - (1 byte) the ID of the already existing key, used to encrypt the new key data. Set it to KEY_EH_AES256_LOADING (0x02) if you want to set the key in encrypted state or 0xFF for plain state.
        - KEY ID - (1 byte) the ID of the key to set, one of the KEY_constants. The TMK cannot be changed with this command.
        - KEY VERSION - (4 bytes) the version of the key in high to low order, 4 bytes, cannot be 0
        - KEY - (variable) the key data, length depends on the key in question, AES256 keys are 32 bytes, DUKPT key is 16 bytes key, 10 bytes serial, 6 bytes for padding (zeroes)
        - HASH - SHA256 of the previous bytes (MAGIC NUMBER, ENCRYPTION KEY ID, KEY ID, KEY VERSION, KEY)
        If using KEY_EH_AES256_LOADING, then KEY + HASH have to be put inside the packet encrypted with AES256 using key KEY_EH_AES256_LOADING. SHA256 is calculated on the unencrypted data. The head decrypt the data and then calculates and compares the hash. If the calculated SHA does not match the SHA sent with the command, the key exchange is rejected and error is returned.
      Throws:
        `EMSRException` - if a reader error occurs.
        `java.io.IOException` - if an I/O error occurs.

    - #### setEncryptionType

          public void setEncryptionType(int type)
                                 throws EMSRException,
                                        java.io.IOException

      Set encryption type.
      Parameters:
        `type` - the encryption type, one of the ENCRYPTION_TYPE_* constants definition.
      Throws:
        `EMSRException` - if a reader error occurs.
        `java.io.IOException` - if an I/O error occurs.

    - #### test

          public int test(int ms)
                   throws EMSRException,
                          java.io.IOException

      Test encrypted magnetic head.
      Parameters:
        `ms` - the timeout of operation.
      Returns:
        the track information.
      Throws:
        `EMSRException` - if a reader error occurs.
        `java.io.IOException` - if an I/O error occurs.

    - #### readCardData

          public byte[] readCardData(int mode)
                              throws EMSRException,
                                     java.io.IOException

      Read card data.
      Parameters:
        `mode` - the mode. If can be combination of MODE_* constant values.
      Returns:
        the encrypted card data.
      Throws:
        `EMSRException` - if a reader error occurs.
        `java.io.IOException` - if an I/O error occurs.