This shows you the differences between two versions of the page.
ac:laboratoare:09 [2024/12/15 04:37] dimitrie.valu |
ac:laboratoare:09 [2024/12/15 06:42] (current) dimitrie.valu |
||
---|---|---|---|
Line 63: | Line 63: | ||
</note> | </note> | ||
+ | <solution -hidden> | ||
+ | From the TLV decoder, you get the following Cardholder Verification Method (CVM) List (''%%8E%%''): | ||
+ | |||
+ | <code> | ||
+ | 000000000000000041000000 | ||
+ | </code> | ||
+ | |||
+ | We have 2 groups of 4 bytes prior to ''%%0x41%%'' - these represent two amount fields (''%%X%%'' and ''%%Y%%''). Not what this task is asking for. | ||
+ | |||
+ | Beyond the two amount fields, we have a variable-length Cardholder Verification Rules (CV Rules) field. Each CV Rule describes a CVM and the conditions under which it should be applied. We only have ''%%0x41%%'' as a CV Rule. If you look at Appendix C3 of EMV Book 3, you can decode it to the following: | ||
+ | |||
+ | <code> | ||
+ | bin(0x41) = 0b01000001 | ||
+ | 0 = RFU (Reserved for Future Use) | ||
+ | 1 = Apply succeeding CV Rule if this CVM is unsuccessful | ||
+ | 000001 = Plaintext PIN verification performed by ICC | ||
+ | </code> | ||
+ | |||
+ | Note that the following CV Rule that would be applied in the case of PIN failure is ''%%0b00000000%%'', i.e. **Fail CVM processing**. | ||
+ | |||
+ | The only cardholder verification method allowed is, hence, plaintext PIN verification. | ||
+ | </solution> | ||
==== 3. Card verification method (2p) ==== | ==== 3. Card verification method (2p) ==== | ||
Line 84: | Line 106: | ||
</note> | </note> | ||
+ | <solution -hidden> | ||
+ | ''%%T->C: 80CA9F1700%%'' | ||
+ | |||
+ | Command APDU Format: ''%%CLA INS P1 P2 Le%%'' | ||
+ | |||
+ | <code> | ||
+ | 80 = (CLA) (class) proprietary class of commands, not ISO 7816-standard. | ||
+ | CA = (INS) (instruction) GET DATA. | ||
+ | From here, we know to look into Book 3, 6.5.7 - GET DATA Command-Response APDUs. | ||
+ | |||
+ | 9F17 = (P1+P2) (parameters 1/2) Tag of data that the terminal is requesting. | ||
+ | In this case, it's PIN Try Counter. | ||
+ | |||
+ | 00 = (Le) Length of command data, 0=no data is being sent with this command. | ||
+ | </code> | ||
+ | |||
+ | ''%%C->T: 6C04%%'' | ||
+ | |||
+ | Status Bytes Format: ''%%SW1 SW2%%'' (Status Bytes 1 and 2) | ||
+ | |||
+ | <code> | ||
+ | 6C = (SW1) Wrong length Le. | ||
+ | 04 = (SW2) The correct, exact length. | ||
+ | </code> | ||
+ | |||
+ | ''%%T->C: 80CA9F1704%%'' | ||
+ | |||
+ | Command APDU Format: ''%%CLA INS P1 P2 Le%%'' | ||
+ | |||
+ | <code> | ||
+ | Same as the first command, but with a correct length: | ||
+ | 04 = (Le) Length of command data, i.e. PIN is 4-bytes long. | ||
+ | </code> | ||
+ | |||
+ | ''%%C->T: CA9F1701069000%%'' | ||
+ | |||
+ | Response APDU Format: ''%%Data SW1 SW2%%'' | ||
+ | |||
+ | <code> | ||
+ | CA = Echo of the INS byte (GET DATA). | ||
+ | 9F17 = The tag for the data object being returned (PIN Try Counter). | ||
+ | 01 = Length of the value being returned, in bytes. | ||
+ | 06 = Value of the data object (i.e. 6 remaining PIN attempts). | ||
+ | 9000 = Operation successful. | ||
+ | </code> | ||
+ | |||
+ | </solution> | ||
==== 4. Card-holder verification (2p) ==== | ==== 4. Card-holder verification (2p) ==== | ||
Line 103: | Line 172: | ||
</note> | </note> | ||
+ | <solution -hidden> | ||
+ | ''%%T->C: 0020008008241111FFFFFFFFFF%%'' | ||
+ | |||
+ | Command APDU Format: ''%%CLA INS P1 P2 Lc Data%%'' | ||
+ | |||
+ | <code> | ||
+ | 00 = (CLA) ISO 7816 class of instructions for standard commands. | ||
+ | 20 = (INS) VERIFY. Used for Cardholder Verification, such as PIN verification | ||
+ | 00 = (P1) PIN verification applies to the currently selected application. | ||
+ | 80 = (P2) Specifies the PIN type and format (plaintext data for 80). | ||
+ | 08 = (Lc) (Length of data) Data field is 8 bytes long. | ||
+ | |||
+ | 241111FFFFFFFFFF = (Data) Of which: | ||
+ | 241111 = The PIN to be verified. | ||
+ | FFFFFFFFFF = Padding (used to fill until 8 bytes). | ||
+ | </code> | ||
+ | |||
+ | ''%%C->T: 9000%%'' | ||
+ | |||
+ | Status Bytes Format: ''%%SW1 SW2%%'' | ||
+ | |||
+ | <code> | ||
+ | 90 = Operation successful. | ||
+ | 00 = No additional information. | ||
+ | </code> | ||
+ | |||
+ | **The card successfully verified the PIN sent by the terminal.** | ||
+ | </solution> | ||
==== 5. Transaction authentication (2p) ==== | ==== 5. Transaction authentication (2p) ==== | ||
Line 123: | Line 220: | ||
</note> | </note> | ||
+ | <solution -hidden> | ||
+ | ''%%T->C: 80AE80002B00000000000000000000000000008000000000000000000000000000003400000000000000000000410002%%'' | ||
+ | |||
+ | Command APDU Format: ''%%CLA INS P1 P2 Lc Data%%'' | ||
+ | |||
+ | **The terminal is sending a Generate Application Cryptogram (GEN AC) command to request an ARQC (Authorisation Request Cryptogram) for transaction authentication.** | ||
+ | |||
+ | <code> | ||
+ | 80 = (CLA) Proprietary command. | ||
+ | AE = (INS) GEN AC (Generate Application Cryptogram). This is used for transaction authentication. | ||
+ | It requests the card to generate a cryptogram to verify the integrity of the transaction. | ||
+ | |||
+ | 80 = (P1) Terminal is requesting an Authorisation Request Cryptogram (ARQC). | ||
+ | 00 = (P2) RFU. | ||
+ | 2B = (Lc) (Length of Data) 43 bytes. | ||
+ | |||
+ | The data itself follows. It is broken into: | ||
+ | 000000000000 = Amount Authorized | ||
+ | 000000000000 = Amount Other | ||
+ | |||
+ | 0800 = Terminal Country Code | ||
+ | 0000 = Transaction Currency Code | ||
+ | 000000 = Transaction Date | ||
+ | 34 = Transaction Type | ||
+ | |||
+ | 0000000000000000 = Unpredictable Number (randomly generated) | ||
+ | 410002 = Data Authentication Code (ARQC input) | ||
+ | </code> | ||
+ | |||
+ | ''%%C->T: 612B%%'' | ||
+ | |||
+ | Status Bytes Format: ''%%SW1 SW2%%'' | ||
+ | |||
+ | <code> | ||
+ | 61 = Card has more data to send. | ||
+ | 2B = 43 bytes of data are available for retrieval. | ||
+ | </code> | ||
+ | |||
+ | ''%%T->C: 00C000002B%%'' | ||
+ | |||
+ | Command APDU Format: ''%%CLA INS P1 P2 Le%%'' | ||
+ | |||
+ | **Here, the terminal is requesting 43 bytes of data from the card.** | ||
+ | |||
+ | <code> | ||
+ | 00 = ISO 7816 standard. | ||
+ | C0 = GET RESPONSE. | ||
+ | 00 = RFU. | ||
+ | 00 = RFU. | ||
+ | 2B = 43 bytes. | ||
+ | </code> | ||
+ | |||
+ | ''%%C->T: C077299F2701809F360201349F2608817C3AAB208BE0659F10120310A00006250400000000000000000000FF9000%%'' | ||
+ | |||
+ | Response APDU Format: ''%%Data SW1 SW2%%'' | ||
+ | |||
+ | <code> | ||
+ | Data is broken into: | ||
+ | C0 = Proprietary or issuer-specific data. | ||
+ | 7729 = Template for cryptogram-related data (EMV tag 77). | ||
+ | |||
+ | Following data is TLV-encoded: | ||
+ | 9F27 = Cryptogram Information Data (CID). | ||
+ | 01 = Length of CID data. | ||
+ | 80 = Cryptogram type: ARQC (Authorisation Request Cryptogram). | ||
+ | |||
+ | 9F36 = Application Transaction Counter (ATC). | ||
+ | 02 = ATC value length. | ||
+ | 0134 = ATC value (Counter = 308). | ||
+ | |||
+ | 9F26 = Application Cryptogram. | ||
+ | 08 = Length of cryptogram. | ||
+ | 817C3AAB208BE065 = The actual cryptogram generated by the card. | ||
+ | |||
+ | 9F10 = Issuer Application Data (IAD). | ||
+ | 12 = Length of IAD. | ||
+ | 0310A00006250400000000000000000000FF = Encrypted issuer-specific data (used for ARQC verification). | ||
+ | |||
+ | 9000 = Operation successful, no more information. | ||
+ | </code> | ||
+ | |||
+ | **The response is concluded with 9000, meaning the operation was successful. This data will be sent to the issuer for further authentication.** | ||
+ | </solution> | ||
==== MAC generation (Bonus) (2p) ==== | ==== MAC generation (Bonus) (2p) ==== | ||
Line 141: | Line 321: | ||
</note> | </note> | ||
- | <hidden> | + | <solution -hidden> |
- | ==== Getting data from your card ==== | + | We should allow students to select the data somewhat arbitrarily as it's not **entirely** provided in the exercises above, as per the minimum spec mentioned in EMV Book 2, page 87, section 8.1.1, table 28. |
- | First, get pyscard from | + | <code python> |
- | [[https://pypi.python.org/pypi/pyscard|here]]. | + | from Crypto.Cipher import DES3 |
+ | from Crypto.Util.Padding import pad | ||
- | Then, install pyscard (check the readme). Do the following (as root): | + | master_key = bytes.fromhex("79610497EFCB67E5546EF8CEBCB05D85") |
- | * Install pcsclite-dev: | + | aip = bytes.fromhex("1000") |
- | <code> | + | |
- | sudo apt-get install libpcsclite-dev | + | |
- | </code> | + | |
- | * Only if the above doesn't work, then install these packages: | + | |
- | <code> | + | |
- | #apt-get install swig libudev-dev git autoconf libtool libsystemd-dev flex | + | |
- | </code> | + | |
- | * Get and install Pyscard from [[https://pypi.python.org/pypi/pyscard|here]] | + | |
- | <code> | + | |
- | #python setup.py build_ext install | + | |
- | </code> | + | |
- | * Install Pyserial | + | |
- | <code> | + | |
- | #sudo pip install pyserial | + | |
- | </code> | + | |
- | If this doesn't work, then get pyserial from [[https://pypi.python.org/pypi/pyserial#downloads|here]] | + | |
- | * Install pcsc related libs: | + | |
- | <code> | + | |
- | sudo apt-get install libusb-dev libusb++-0.1-4v5 libccid pcscd libpcsclite1 | + | |
- | </code> | + | |
- | * Only if desired, additional tools can be installed from here: | + | |
- | <code> | + | |
- | #apt-get install libpcsc-perl | + | |
- | #apt-get install pcsc-tools | + | |
- | </code> | + | |
- | See details [[http://support.gemalto.com/fileadmin/user_upload/IAM/FAQ/How_to_install_the_PC-Link_reader_on_Linux.pdf|here]]. | + | |
+ | # concatenation of amount authorised and amount other, | ||
+ | # terminal country code, transaction currency code, | ||
+ | # transaction date, transaction type, | ||
+ | # unpredictable number, given AIP and the ATC | ||
+ | # we aren't given the terminal verification results, | ||
+ | # so I assumed that it's gonna be 5 * b'00' | ||
+ | transaction_data = bytes.fromhex( | ||
+ | "00000000000000000000000008000000000000000000000034000000000000000010000134" | ||
+ | ) # from task 5 | ||
+ | # 3DES block size is 8 bytes | ||
+ | padded_data = pad(transaction_data, 8) | ||
- | Files for accessing card data [[https://ocw.cs.pub.ro/courses/_media/ac/laboratoare/sclink.zip|here]]. | + | # 3DES encryption |
- | </hidden> | + | cipher = DES3.new(master_key, DES3.MODE_ECB) |
+ | mac = cipher.encrypt(padded_data) | ||
+ | |||
+ | mac = mac.hex() | ||
+ | print(mac) | ||
+ | </code> | ||
+ | </solution> | ||