ISO 7816 APDU for Smart Card using javax.smartcardio - java

I've already used javax.smartcardio to read serial number from smart card without much effort. However now I'm assigned to create MF on blank card (without which serial number can't be read).I'm creating APDU command for that as per ISO 7816 guidelines,but unable to create proper APDU command because my hex values are getting converted to wrong bytes.
import javax.smartcardio.Card;
import javax.smartcardio.CardChannel;
import javax.smartcardio.CardException;
import javax.smartcardio.CardTerminal;
import javax.smartcardio.CommandAPDU;
import javax.smartcardio.ResponseAPDU;
import javax.smartcardio.TerminalFactory;
class SmartCardAPIs {
public int Create_MF() throws CardException{
//--Variable declaration
int result=0;
Card card=null;
byte[] responseData=null;
ResponseAPDU answer=null;
String SW1=null;
String SW2=null;
int cla, ins, p1, p2;
byte[] data=null;
//---------------------------------------------
//--1--Establish connection with the smart card
TerminalFactory factory = TerminalFactory.getDefault();
List<CardTerminal> terminals = factory.terminals().list();
// Use the first terminal
CardTerminal terminal = terminals.get(0);
// Connect with the card
card = terminal.connect("*");
CardChannel channel = card.getBasicChannel();
//---------------------------------------------
//--2--Create MF
cla=0x00;
ins=0xE0;
p1=0x00;
p2=0x00;
data = new byte[] {
(byte) 0x21,
(byte) 0x62,
(byte) 0x1F,
(byte) 0x82, // **** Getting converted to -126 ****
--
--
--
};
answer = channel.transmit(new CommandAPDU(cla, ins, p1, p2, data));
responseData= answer.getBytes();
if(responseData!=null)
{
if(responseData.length==2)
{
SW1=String.format("%02X ", (responseData[0])).trim();
SW2=String.format("%02X ", (responseData[1])).trim();
}
}
}
}
I've 2 problems
1: data in command APDU is taking a byte which is wrong(marked as *).
2: SW1 and SW2 are returning as 6A 80 which means parameter in data field are incorrect(I guess because of negative value while casting int in hex format to byte,but can not help much as I'm forced to do it).
The partial APDU command which I've placed here is part of full command which I've been supplied ,and the command is 100% OK and tested as I've been successful in creating MF in blank card using smart card tools with the command.I want to do the same in java now.
I assume that problem lies with the way this APDU is being getting created,may be negative value problem(I'm not very expert with java APDU stuffs although I 've created Applet to read serial number from card).

Since you say, you have a working command at hand and surely double-checked its java representation: how sure are you, that the command did not execute successfully in a preceeding attempt? (Obviously only one MF is allowed.) Problem is, that the reported error code contradicts the "correct APDU known" assumption and this is the only resolution I can think of. The java code looks correct, as far as it is given.
Other idea: The command data field of an ISO Create File should start with something like 0x6X for FCI. Possibly your 0x21 is the length of the whole template (supposed to be sent as LC), which java constructs itself from the length of the byte array, so try leaving it out.
The fact, that the 3rd byte is 0x1F, meaning 0x21 minus tag and length, supports that hypothesis.

I have tried this command :
..
..
private static final byte[] Select_App = {(byte)0x00,(byte)0xA4,(byte)0x04,(byte)0x00,(byte)0x04,(byte)0x50,(byte)0x54,(byte)0x4B,(byte)0x65};
..
..
and they worked fine, I got the right respons from the card. But I tried that command on android. So I think that byte casting is right we don't need to convert anything
Well, about java.smartcardio.*; I have the same problem with you, I can't send any command using that librari. But someone said that I have to use some java wrapper to send some commands. Umm... I'm still working on it btw... :-)

You need to convert byte to hex properly by following Methods.
Integer class = StringUtil.parseHex("your class as string");
Class StringUtil
public class StringUtil {
public static Integer parseHex(String iStr) {
int mask = 255;
if (iStr.length() > 2)
mask = 65535;
try {
return Integer.valueOf(Integer.parseInt(iStr, 16) & mask);
} catch (Exception ex) {
}
return null;
}

Related

Writing ASCII Values Into the Register of Serial Communication Devices Like RS485

I am creating a java Desktop Application. I want to write the data into the register of a device. As per my project document, size of the register is 16-bit long. I am using EasyModbusJava jar to write data into the register. Till now I have written some integer data on the device's register. Now I want to write the ascii of 32 characters at 16 consecutive register(2 Character per Register). But issue is that the available methods for writing on the registers takes int as an argument. If am passing the short(int) array of ascii values then it needs to be typecast which means that it will no longer be acquiring the size of the short data type.
There are two methods are available to write into the registers address.
For Writing at Single Register
public void WriteMultipleRegisters(int startingAddress, int[] values){...}
For Writing at Multiple Register
public void WriteMultipleRegisters(int startingAddress, int[] values){...}
Suggest some way to resolve my issue.
Below is the link of the jar file documentation which I am using in my project.
Docs of Jar File.
I think the easiest thing to do is use a ByteBuffer to manage this byte manipulation. Something like,
char[] arr = "Hello, World".toCharArray();
ByteBuffer bb = ByteBuffer.allocate(arr.length);
for (char ch : arr) {
bb.put((byte) ch);
}
bb.rewind();
// You may need a call to ByteBuffer.order(ByteOrder) here.
for (int i = 0; i < arr.length / 2; i++) {
int v = bb.getShort(); // Reads two bytes and converts to 16-bit short integer
System.out.println(v);
}

How can I get the byte array value returned from a bluetooth incoming message and edit it before displaying it on the other device?

So I asked this question a few days ago, but maybe I can elaborate a bit more, or in a different way now. I am a big java and android newbie, so it takes a lot of time to figure stuff out for me. I have a Bluetooth connecting between 2 devices. I tried using sensors and everything works fine. The devices connect and they send sensor values to one another.
This sensor value, however, is auto-generated. What I want is to get DB values from one of the devices, convert them to bytes, add them to a byte array and send this byte array as a single message to the other device, where it is going to reverse the process. I have everything set up, everything is as it should be with only 1 exception - I need to somehow catch the incomingMessage as a byte array, so I can finish the process.
How can I get the value of the incomingMessage(which is supposed to be transferring a byte array) and add it to another byte array that I am then "decoding"?
The commented out one is the example that I tried and was working.
if (mBluetoothConnection.incomingMessage != null) {
//messageTemp = mBluetoothConnection.incomingMessage;
msg = mBluetoothConnection.incomingMessage;
}
The one that is not commented out is the one, whose value I want to assign to a byte array:
byte[] array = msg;
This is the only thing that I have not been able to figure out so far.
My current issue is that "array" returns null object reference.
Please, help me! I feel like I have almost connected 2 bridges and the paint on each differest by just a centimeter from being okay.
Alright, I managed to figure it out, but forgot to update, here is my other post with a little bit more code:
How can I assing the value of an incoming Bluetooth message to a byte array which I want to decode into integers?
Here's what I changed:
I only touched the run() method in my BluetoothConnectionService
Instead of using the byte[] buffer, as I mention in the commented code, I declared a public static byte[] incomingBytes and gave it a size of 44, since this is what my 11 integer array going to need. Then I just replaced the "buffer" with "incomingBytes" in the example code, and looks like this:
public static byte[] incomingBytes = new byte[44];
public void run(){
//byte [] buffer replaced with incomingBytes
byte[] buffer = new byte[44]; // this was in the example, but it is not used. It was replaced by incomingBytes, declared at the start of the class
int bytes; // bytes returned from read()
// Keep listening to the InputStream until an exception occurs
while (true) {
// Read from the InputStream
try {
bytes = mmInStream.read(incomingBytes);
incomingMessage = new String(incomingBytes, 0, bytes);
Log.d(TAG, "InputStream: " + incomingMessage);
} catch (IOException e) {
Log.e(TAG, "write: Error reading Input Stream. " + e.getMessage() );
break;
}
}
}
Then I only need to call incomingBytes for my convertion in the other class and it works fine.

Fixing the Aztec decoder in Zxing (Obj-C) to return raw ByteArray

I'm working on an iOS app that's supposed to decode a certain type of Aztec barcode (example, PDF). I need the scanner to return the data on a low level, since it's zlib compressed and I need to decompress it afterwards. The built-in barcode scanner using AVCapture works fine for regular string data but fails in my case.
I have turned to Zxing, or rather its Objective C port ZXingObjC, in the hope of being able to access the decoded barcode data before it gets turned into a string. I was half successful. The ZXResult returned does contain a ZXByteArray called rawBytes, but only for QR codes (for Aztec codes it's nil)! I looked inside ZXAztecDecoder.m and sure enough, the byte array is never populated, not even in the original Zxing code in Java.
Someone tried to fix it for the original library (Pull Request, Line 80) by doing
byte[] rawBytes = convertBoolArrayToByteArray(correctedBits);
I'd like to add the same functionality for ZXingObjC, but I'm stuck trying to convert theZXBoolArray to a ZXByteArray. Here is the decode function as I envision it:
- (ZXDecoderResult *)decode:(ZXAztecDetectorResult *)detectorResult error:(NSError **)error {
self.ddata = detectorResult;
ZXBitMatrix *matrix = [detectorResult bits];
ZXBoolArray *rawbits = [self extractBits:matrix];
if (!rawbits) {
if (error) *error = ZXFormatErrorInstance();
return nil;
}
ZXBoolArray *correctedBits = [self correctBits:rawbits error:error];
if (!correctedBits) {
return nil;
}
ZXByteArray *rawBytes = /* somehow turn correctedBits into ZXByteArray */;
NSString *result = [[self class] encodedData:correctedBits];
return [[ZXDecoderResult alloc] initWithRawBytes:rawBytes text:result byteSegments:nil ecLevel:nil];
}
If somebody knows how to do this or has an idea how to go about it, I'd appreciate it. If it works out, I'd like to contribute the code to ZXingObjC, so this won't bug people in the future. Thanks in advance!
It's not actually a solution to the problem, but my persistent nagging helped fix this overdue issue in the original ZXing Github repo. If that change makes it upstream into ZXingObjC at some point, I can close this question for good.
If anybody wants to help translate these Java lines (source) to Objective-C, I'd surely appreciate it.
/**
* Reads a code of length 8 in an array of bits, padding with zeros
*/
private static byte readByte(boolean[] rawbits, int startIndex) {
int n = rawbits.length - startIndex;
if (n >= 8) {
return (byte) readCode(rawbits, startIndex, 8);
}
return (byte) (readCode(rawbits, startIndex, n) << (8 - n));
}
/**
* Packs a bit array into bytes, most significant bit first
*/
static byte[] convertBoolArrayToByteArray(boolean[] boolArr) {
byte[] byteArr = new byte[(boolArr.length + 7) / 8];
for (int i = 0; i < byteArr.length; i++) {
byteArr[i] = readByte(boolArr, 8 * i);
}
return byteArr;
}

How to parse byte stream in Java properly

Hello boys and girls.
I'm developing a terminal based client application which communicates over TCP/IP to server and sends and receives an arbitary number of raw bytes. Each byte represents a command which I need to parse to Java classes representing these commands, for further use.
My question how I should parse these bytes efficiently. I don't want to end up with bunch of nested ifs and switch-cases.
I have the data classes for these commands ready to go. I just need to figure out the proper way of doing the parsing.
Here's some sample specifications:
Byte stream can be for example in
integers:[1,24,2,65,26,18,3,0,239,19,0,14,0,42,65,110,110,97,32,109,121,121,106,228,42,15,20,5,149,45,87]
First byte is 0x01 which is start of header containing only one byte.
Second one is the length which is the number of bytes in certain
commands, only one byte here also.
The next can be any command where the first byte is the command, 0x02
in this case, and it follows n number of bytes which are included in
the command.
So on. In the end there are checksum related bytes.
Sample class representing the set_cursor command:
/**
* Sets the cursor position.
* Syntax: 0x0E | position
*/
public class SET_CURSOR {
private final int hexCommand = 0x0e;
private int position;
public SET_CURSOR(int position) {
}
public int getPosition() {
return position;
}
public int getHexCommnad() {
return hexCommand;
}
}
When parsing byte streams like this the best Design Pattern to use is the Command Pattern. Each of the different Commands will act as handlers to process the next several bytes in the stream.
interface Command{
//depending on your situation,
//either use InputStream if you don't know
//how many bytes each Command will use
// or the the commands will use an unknown number of bytes
//or a large number of bytes that performance
//would be affected by copying everything.
void execute(InputStream in);
//or you can use an array if the
//if the number of bytes is known and small.
void execute( byte[] data);
}
Then you can have a map containing each Command object for each of the byte "opcodes".
Map<Byte, Command> commands = ...
commands.put(Byte.parseByte("0x0e", 16), new SetCursorCommand() );
...
Then you can parse the message and act on the Commands:
InputStream in = ... //our byte array as inputstream
byte header = (byte)in.read();
int length = in.read();
byte commandKey = (byte)in.read();
byte[] data = new byte[length]
in.read(data);
Command command = commands.get(commandKey);
command.execute(data);
Can you have multiple Commands in the same byte message? If so you could then easily wrap the Command fetching and parsing in a loop until the EOF.
you can try JBBP library for that https://github.com/raydac/java-binary-block-parser
#Bin class Parsed { byte header; byte command; byte [] data; int checksum;}
Parsed parsed = JBBPParser.prepare("byte header; ubyte len; byte command; byte [len] data; int checksum;").parse(theArray).mapTo(Parsed.class);
This is a huge and complex subject.
It depends on the type of the data that you will read.
Is it a looooong stream ?
Is it a lot of small independent structures/objects ?
Do you have some references between structures/objects of your flow ?
I recently wrote a byte serialization/deserialization library for a proprietary software.
I took a visitor-like approach with type conversion, the same way JAXB works.
I define my object as a Java class. Initialize the parser on the class, and then pass it the bytes to unserialize or the Java object to serialize.
The type detection (based on the first byte of your flow) is done forward with a simple case matching mechanism (1 => ClassA, 15 => ClassF, ...).
EDIT: It may be complex or overloaded with code (embedding objects) but keep in mind that nowadays, java optimize this well, it keeps code clear and understandable.
ByteBuffer can be used for parsing byte stream - What is the use of ByteBuffer in Java?:
byte[] bytesArray = {4, 2, 6, 5, 3, 2, 1};
ByteBuffer bb = ByteBuffer.wrap(bytesArray);
int intFromBB = bb.order(ByteOrder.LITTLE_ENDIAN).getInt();
byte byteFromBB = bb.get();
short shortFromBB = bb.getShort();

Using assertArrayEquals() with wildcards?

I want to test code that produces byte arrays used to send as UDP packets.
Although I'm not able to reproduce every byte in my test (e.g. random bytes, timestamps), I'd like to test the bytes that I can predetermine.
Is something like the following possible using JUnit 4.8 (and Mockito 1.8)?
Packet packet = new RandomPacket();
byte[] bytes = new byte[] {
0x00, 0x02, 0x05, 0x00, anyByte(), anyByte(), anyByte(), anyByte(), 0x00
};
assertArrayEquals(packet.getBytes(), bytes);
The sample above is of course not working, I'm just searching for a way to use some sort of wildcard in assertArrayEquals().
PS: My only alternative right now is to check each byte individually (and omit random ones). But this is quiet tedious and not really reusable.
Thanks to the answer from JB Nizet I have the following code in place now, working just fine:
private static int any() {
return -1;
}
private static void assertArrayEquals(int[] expected, byte[] actual) {
if(actual.length != expected.length) {
fail(String.format("Arrays differ in size: expected <%d> but was <%d>", expected.length, actual.length));
}
for(int i = 0; i < expected.length; i ++) {
if(expected[i] == -1) {
continue;
}
if((byte) expected[i] != actual[i]) {
fail(String.format("Arrays differ at element %d: expected <%d> but was <%d>", i, expected[i], actual[i]));
}
}
}
You could simply write your expected array as an array of integers, and use a special value (such as -1) to represent the wildcard. It's the same trick as the read methods of the input streams. You would just have to write your custom assertEqualsWithWildCard(int[] expected, byte[] actual).
If you are going to be writing a lot of code like this, I would write a separate class to "decode" the packet into meaningful fields. Then (of course, after testing that the class itself works) you can write sensible tests like
assertEquals(42, packet.length());
assertEquals(0xDEADBEEF, packet.checksum());
etc.
That way, you are not "omitting random bytes", and your code will be much more readable (if a tad more verbose).

Categories