I'm currently working a project with Open Mobile API. Basically, I got this problem when i exchange apdu to the UICC, all my commands converted automatically to the extended logical APDU command (CLA : 0xC1). I'm using Samsung Galaxy S6 Edge during this test with android version : 5.0.2.
APDU > Header [CLA INS P1 P2] 00 70 00 00 194,69 etu MANAGE CHANNEL
< Outgoing data 01
< Return code [SW1 SW2] 90 00
APDU > Header [CLA INS P1 P2] 01 A4 04 00 194,69 etu SELECT
Incoming data A0 00 00 05 59 10 10 FF FF FF FF 89 00 00 01 00
< Outgoing data 6F 1A 84 10 A0 00 00 05 59 10 10 FF FF FF FF 89
00 00 01 00 A5 06 73 00 9F 65 01 FF
< Return code [SW1 SW2] 90 00
APDU > Header [CLA INS P1 P2] C1 E2 91 00 187,69 etu
Incoming data BF 2D 00
< Return code [SW1 SW2] 6D 00
APDU > Header [CLA INS P1 P2] 00 70 80 01 192,69 etu MANAGE CHANNEL
< Return code [SW1 SW2] 90 00
What could be a problem? Who is responsible to change my CLA command to 0xC1? Why the phone change the CLA command to 0xC1?
Note : Based on my application log, I send this 81 E2 91 00 02 BF 2D 00
Thanks for your help.
Related
I am trying to read the information stored on my German Sparkasse Girocard. My app successfully recognizes the (ISODEP) tag. To read the stored information, I need to send a sequence of APDU commands, but I am not sure which.
From my understanding I need to send a SELECT command first:
byte[] SELECT = {
(byte) 0x00, // CLA Class
(byte) 0xA4, // INS Instruction
(byte) 0x04, // P1 Parameter 1
(byte) 0x00, // P2 Parameter 2
(byte) 0x09, // Lc
(byte) 0xD2,0x76,0x00,0x00,0x25,0x47,0x41,0x01,0x00, // AID
(byte) 0x00 //Le
};
Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
IsoDep tag = IsoDep.get(tagFromIntent);
tag.connect();
byte[] result = tag.transceive(SELECT);
text.setText(Integer.toHexString(result[0]) + ", " + Integer.toHexString(result[1]));
The status response should be 9000 if it works. I am getting 6F44 which indicates that there was some sort of error (I think). I am also not quite sure if I am using the correct AID, but it has also not worked using others, which I thought could be correct.
What is my error and which commands do I have to send to retrieve the data?
Thanks in advance.
Getting data from an EMV card (e.g. Girocard, Mastercard, Visacard) is more a "question and answer" puzzle - you are asking the card, get a response, analyze the data and ask the next question.
The analyzing part is done here by using the "TLV Utilities" from emvlab.org (https://emvlab.org/tlvutils/).
To get more information about the Application Identifier ("AID"s) see the complete list at: https://www.eftlab.com/knowledge-base/211-emv-aid-rid-pix/.
Here is an example of reading a German Girocard (mine is from a "Volksbank"):
Step 1: ask the card which applications are on the card using the "select PPSE" command. The 2 bytes at the end "90 00" say that the answer is successfull:
selectPpseCommand: 00 A4 04 00 0E 32 50 41 59 2E 53 59 53 2E 44 44 46 30 31 00
selectPpseResponse: 6F 67 84 0E 32 50 41 59 2E 53 59 53 2E 44 44 46 30 31 A5 55 BF 0C 52 61 19 4F 09 A0 00 00 00 59 45 43 01 00 87 01 01 9F 0A 08 00 01 05 01 00 00 00 00 61 1A 4F 0A A0 00 00 03 59 10 10 02 80 01 87 01 01 9F 0A 08 00 01 05 01 00 00 00 00 61 19 4F 09 D2 76 00 00 25 47 41 01 00 87 01 01 9F 0A 08 00 01 05 01 00 00 00 00 90 00
Parsed response:
6F File Control Information (FCI) Template
84 Dedicated File (DF) Name
325041592E5359532E4444463031
A5 File Control Information (FCI) Proprietary Template
BF0C File Control Information (FCI) Issuer Discretionary Data
61 Application Template
4F Application Identifier (AID) – card
A00000005945430100
87 Application Priority Indicator
01
9F0A Unknown tag
0001050100000000
61 Application Template
4F Application Identifier (AID) – card
A0000003591010028001
87 Application Priority Indicator
01
9F0A Unknown tag
0001050100000000
61 Application Template
4F Application Identifier (AID) – card
D27600002547410100
87 Application Priority Indicator
01
9F0A Unknown tag
0001050100000000
There are 3 applications with 3 different AIDs available on the card:
A00000005945430100: Zentraler Kreditausschuss (ZKA) Germany Girocard Electronic Cash
A0000003591010028001: Euro Alliance of Payment Schemes s.c.r.l. – EAPS Belgium Girocard EAPS ZKA (Germany)
D27600002547410100: ZKA Germany Girocard ATM
Step 2: Now I'm reading the first AID using the "Select AID" command - the AID is 18 characters = 9 bytes long:
selectAidCommand: 00 A4 04 00 09 A0 00 00 00 59 45 43 01 00 00
selectAidResponse: 6F 47 84 09 A0 00 00 00 59 45 43 01 00 A5 3A 50 08 67 69 72 6F 63 61 72 64 87 01 01 9F 38 06 9F 02 06 9F 1D 02 5F 2D 04 64 65 65 6E BF 0C 1A 9F 4D 02 19 0A 9F 6E 07 02 80 00 00 30 30 00 9F 0A 08 00 01 05 01 00 00 00 00 90 00
Parsed response:
6F File Control Information (FCI) Template
84 Dedicated File (DF) Name
A00000005945430100
A5 File Control Information (FCI) Proprietary Template
50 Application Label
g i r o c a r d
87 Application Priority Indicator
01
9F38 Processing Options Data Object List (PDOL)
9F02 06
9F1D 02
5F2D Language Preference
d e e n
BF0C File Control Information (FCI) Issuer Discretionary Data
9F4D Log Entry
190A
9F6E Unknown tag
02800000303000
9F0A Unknown tag
0001050100000000
Step 3: get the processing options to read the card details
This is the first "tricky" point as it is not easy how to explain to get the right data for your card/AID. In the above response there is a section for the Processing Options Data Object List (PDOL) the card is requesting and the length of the fields - here we do have 2 fields with a length of 6 and 2 bytes, in total 8 bytes. The 8 bytes are just 8 "x00"s with the "header" 83 08, so the complete length is 10 bytes = x0A:
9F38 Processing Options Data Object List (PDOL)
9F02 06
9F1D 02
A more detailed explanation can be found here: https://stackoverflow.com/a/20810855/8166854
getProcessingOptionsCommand: 80 A8 00 00 0A 83 08 00 00 00 00 00 01 00 00 00
getProcessingOptionsResponse: 77 1E 82 02 19 80 94 18 18 01 01 00 20 01 01 00 20 04 04 00 08 05 05 01 08 07 07 01 08 03 03 01
Parsed response:
77 Response Message Template Format 2
82 Application Interchange Profile
1980
94 Application File Locator (AFL)
18010100 20010100 20040400 08050501 08070701 08030301
The most important part for the next step is the "Application File Locator (AFL)" - we need to read the file system with the data that are coded in these 4 byte blocks.
Step 4: read the records from the card
This is the part where I get lost when trying to read the card. You need to get the SFI and RECORD from the first 3 bytes of an AFL block and run a read record command. The following command reads the 4th sector of the AFL list - the command may work or not with your card and if it works you may get different data from your card.
WARNING: providing the response data to an internet form may reveal data like account number or
credit card number - my response is masked so the account number is not 1111111111:
readRecordCommand: 00 B2 05 0C 00
readRecordResponse: 70 38 5F 24 03 21 12 31 5A 0A 67 26 42 89 11 11 11 11 11 7F 5F 34 01 02 5F 28 02 02 80 9F 07 02 FF C0 9F 0D 05 FC 40 A4 80 00 9F 0E 05 00 10 18 00 00 9F 0F 05 FC 40 A4 98 00 90 00
Parsed response:
70 EMV Proprietary Template
5F24 Application Expiration Date
211231
5A Application Primary Account Number (PAN)
6726428911111111117F
5F34 Application Primary Account Number (PAN) Sequence Number
02
5F28 Issuer Country Code
0280
9F07 Application Usage Control
FFC0
9F0D Issuer Action Code – Default
FC40A48000
9F0E Issuer Action Code – Denial
0010180000
9F0F Issuer Action Code – Online
FC40A49800
I strongly recommend that you use a library for the steps 3 and 4; I'm using
https://github.com/devnied/EMV-NFC-Paycard-Enrollment
for this.
This is just a basic explanation for the first steps but now you get some useful responds from your card - good luck for your next steps.
A complete Android example app for the above mentioned library is here (disclaimer: I'm the author):
https://github.com/AndroidCrypto/Android-EMV-NFC-Paycard-Example
Followed by the sample, I started my Pi with the command:
pi#raspberrypi ~ $ sudo hciconfig hci0 up
pi#raspberrypi ~ $ hciconfig
hci0: Type: BR/EDR Bus: USB
BD Address: 00:1A:7D:DA:71:13 ACL MTU: 310:10 SCO MTU: 64:8
UP RUNNING
RX bytes:1094 acl:0 sco:0 events:54 errors:0
TX bytes:768 acl:0 sco:0 commands:54 errors:0
pi#raspberrypi ~ $ sudo hcitool -i hci0 cmd 0x08 0x0008 1e 02 01 1a 1a ff 4c 00 02 15 e2 c5 6d b5 df fb 48 d2 b0 60 d0 f5 a7 10 96 e0 00 00 00 00 c5 00 00 00 00 00 00 00 00 00 00 00 00 00
< HCI Command: ogf 0x08, ocf 0x0008, plen 44
1E 02 01 1A 1A FF 4C 00 02 15 E2 C5 6D B5 DF FB 48 D2 B0 60
D0 F5 A7 10 96 E0 00 00 00 00 C5 00 00 00 00 00 00 00 00 00
00 00 00 00
> HCI Event: 0x0e plen 4
01 08 20 12
pi#raspberrypi ~ $ sudo hciconfig hci0 leadv 3
Then, turned on my Android 4.4 phone which works perfectly with the Ibeacon devices I ordered from online retailers(no brand).
works perfectly means I can see all the advertising data in Java code(by following onLeScan(...) callback), as well as the RSSI, and parsing them(UUID, major, minor and etc.).
The strange thing is I put a debug info into:
public synchronized void onLeScan(final BluetoothDevice device,
int rssi, byte[] scanRecord)
the byte[] scanRecord I got from PI is:
02 01 0A 02 0A 08 0C 09 43 53 52 38 35 31 30 20 41 31 30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
I can't read these bytes which seems totally mismatched with the one set via Pi command line, I tried with the App IBeacon Locate, still couldn't find my Pi, please help, thanks.
Add more details:
Only the BLE dongle is a different brand from the sample since I'm not in US, and I'm not sure if its drivers were installed correctly in PI and actually I didn't explicitly installed any drivers for it(I'm a new guy for Linux), I just pulg in and started the command line.
Some folks with different bluetooth dongles have reported having to alter the order of the commands and disabling advertising before enabling it. Try:
sudo hciconfig hci0 up
sudo hciconfig hci0 noleadv
sudo hciconfig hci0 leadv
sudo hcitool -i hci0 cmd 0x08 0x0008 1e 02 01 1a 1a ff 4c 00 02 15 e2 c5 6d b5 df fb 48 d2 b0 60 d0 f5 a7 10 96 e0 00 00 00 00 c5 00 00 00 00 00 00 00 00 00 00 00 00 00
You might also let us know the model of your bluetooth dongle and what it reports itself as to Linux. You can see this by typing lsusb
BTW, nice job capturing the bytes read by Android's onLEScan method. Super helpful!
I'm still trying to emulate a point of sale (POS) system and complete a transaction with Google wallet.
I've gotten further with great answers on stack overflow.
See Android isoDep.transceive on Generate AC command always returns 6D00 unsupported
Even though every step of the communication from the POS and Google Wallet is successful, I can't get past Google wallet stating
"Status unknown, Check with cashier to see if the payment was successful".
I just need Google wallet to state "Status pending" just like at McDonalds (in the US).
I actually don't care if the whole transaction processes and clears my bank.
I'm new to transaction processing and it seems like I'm missing a fundamental step.
Any ideas would be greatly appreciated.
The following are the successful steps.
Step 1 Select Proximity Payment System Environment (2PAY.SYS.DDF01)
Send = 00 A4 04 00 0E 32 50 41 59 2E 53 59 53 2E 44 44 46 30 31 00
Response = 6f2f 840e 325041592e5359532e4444463031 a51d bf0c1a61184f07a00000 00041010870101500a4d 617374657243617264 9000 (Success)
Step 2 Select Payment Service
Send = 00 A4 04 00 07 A0 00 00 00 04 10 10 00
Response = 6f1e 8407 a0000000041010 a513 500a 4d617374657243617264 870101 9f11 01 01 9000 (Success)
Step 3 Get Processing Options
Send = 80 a8 00 00 02 83 00 00
Response = 770a 8202 0000 9404 08010100 9000 (Success)
Step 4 Read Record
Send = 00 B2 01 0C 00
Response = 70 7c 9f 6c 02
00 01 9f 62 06
00 00 00 00 00
38 9f 63 06 00
00 00 00 03 c6
56 29 42 35 33
39 36 XX XX XX
XX 31 XX XX 39
XX XX XX XX 5e
20 2f 5e 31 34
30 37 31 30 31
34 30 31 30 30
30 30 30 30 30
30 30 30 9f 64
01 04 9f 65 02
00 38 9f 66 02
03 c6 9f 6b 13
53 96 XX XX 1X
X9 XX XX d1 40
71 01 40 10 00
00 00 00 0f 9f
67 01 04 9f 69
0f 9f 6a 04 9f
7e 01 9f 02 06
5f 2a 02 9f 1a
02 9000 (Success)
Step 5 Compute Crytographic Checksum
Send = 80 2A 8E 80 0F 00 00 00 12 00 00 00 00 00 01 00 08 40 08 40 00
Response = 77 0f 9f 61 02 XX XX 9f 60 02 XX XX 9f 36 02 20 fa 9000 (Success)
The "PayPass – M/Chip Transaction Processing" specification states
"After the completion of the COMPUTE CRYPTOGRAPHIC CHECKSUM response, the
PayPass card can be removed from the PayPass reader."
So I assumed POS to Google Wallet communication was done, but Google Wallet seems to need more information.
So I assumed POS to Google Wallet communication was done, but Google Wallet seems to need more information.
Correct. Google Wallet retrieves information about transactions trough the card issuer's online backend system (at least that was the case with pre 2.0 version of GW, but I would assume that's still the case). Thus if you do not perform a real transaction (one that runs through the Master Card network), Google Wallet has no means to retrieve details about the transaction for the online backend.
I am using the following code to read a structured binary file
FileInputStream objIS = new FileInputStream("/sdcard/waverider.usr");
DataInputStream objBR = new DataInputStream(objIS);
objwVer = objBR.readShort();
objwSVer = objBR.readShort();
objNoWaypoints = objBR.readShort();
System.out.println(objwVer);
System.out.println(objwSVer);
System.out.println(objNoWaypoints);
objIS.close();
This produces the result:
512
0
8706
The result I am after is
2
0
546
That is what I get with VB.net using:
objwVer = objBR.ReadInt16
objwSVer = objBR.ReadInt16
objNoWaypoints = objBR.ReadInt16
The binary file is as follow:
02 00 00 00 22 02 00 00 4b a9 c8 ff b2 2d 33 00
00 00 00 00 04 00 00 00 48 6f 6d 65 00 00 00 00
1c 68 53 0d 10 27 00 00 00 00 01 00 7e 8c c8 ff
Am I missing something here
9d 33 33 00 00 00 00 00 06 00 00 00
Your problem is that
your file is written in little endian byte order but your code is expecting big endian byte order.
Your stream is encoded in little-endian and DataInputStream only supports big-endian.
You could use ByteBuffer instead, which allows to parse little-endian formatted stream: http://developer.android.com/reference/java/nio/ByteOrder.html#LITTLE_ENDIAN
try JBBP framework, it is android compatible and its JBBPBitInputStream allows read data in different byte and bit order
new JBBPBitInputStream(in).readInt(JBBPByteOrder.LITTLE_ENDIAN);
In one of my application, I open binary files, and I got some error report by users on some files. When they send me the files, if I download them on Gmail in the desktop, the file displays nicely in my app. When I download them with the native Android GMail app, the file doesn't open.
Here are the first 64 bytes of the original file, and as it appear when downloaded from the desktop (displayed as hexa):
03 00 08 00 D8 0C 00 00 01 00 1C 00 BC 02 00 00
2D 00 00 00 00 00 00 00 00 01 00 00 D0 00 00 00
00 00 00 00 00 00 00 00 10 00 00 00 25 00 00 00
33 00 00 00 3D 00 00 00 44 00 00 00 49 00 00 00
And here are the first 64 bytes of the file downloaded with the native GMail app (hexa again) :
EF BF BD EF BF BD 2D EF BF BD 25 33 3D 44 49 4D
52 63 72 76 EF BF BD EF BF BD EF BF BD EF BF BD
EF BF BD EF BF BD EF BF BD EF BF BD EF BF BD EF
BF BD EF BF BD 29 2E 3E 43 54 59 69 6E 7F EF BF
Is there a sort of compression applied to this file or is the GMail app corrupting it ? Especially if you look at the end of the first sample, you have the following bytes 10, 25, 33, 3D, 44, 49, which also appear in the first line of the second sample, which leed me to think that it's a compression of some sort.
I'm not sure of the exact source, but if you look at http://www.cogsci.ed.ac.uk/~richard/utf-8.cgi?input=%F6&mode=char then that pattern is due to something trying to interpret the file as UTF-8, doing replacement, then writing the file as UTF-8.