我已经使用javax.smartcardio读取智能卡上的序列号,而不费太大力气。然而,现在我被指派在空白卡上创建MF (如果没有这个序列号就不能读取),我正在按照ISO 7816准则创建APDU命令,但是无法创建正确的APDU命令,因为我的十六进制值被转换成了错误的字节。
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();
}
}
}
}我有两个问题
1:命令APDU中的数据正在接受一个错误的字节(标记为*)。
2: SW1和SW2作为6A80返回,这意味着数据字段中的参数是不正确的(我猜是因为在将int转换为十六进制格式时出现了负值,但我不得不这样做。
我在这里放置的部分APDU命令是我所提供的完整命令的一部分,该命令是100% OK并经过测试,因为我已经成功地使用带有命令的智能卡工具在空白卡中创建MF,我现在想在java中做同样的事情。
我认为问题在于创建APDU的方式,可能是负值问题(虽然我创建Applet是为了从卡片中读取序列号,但我对java APDU的内容并不十分精通)。
发布于 2012-12-13 08:10:43
既然您说,您手头有一个工作命令,并且肯定会对其java表示进行双重检查:您有多确定,该命令在前面的尝试中没有成功执行?(显然只允许一种MF。)问题是,报告的错误代码与“正确的APDU已知”假设相矛盾,这是我唯一能想到的解决方案。只要给出java代码,它就看起来是正确的。
其他想法: ISO Create File的命令数据字段应该以类似于FCI的0x6X开头。您的0x21可能是整个模板的长度(应该以LC的形式发送),java根据字节数组的长度构造自己,所以尝试将其排除在外。第三个字节是0x1F,意思是0x21减号和长度,这一事实支持这一假设。
发布于 2014-05-22 06:39:43
我试过这样的命令:
。。
。。
private static final byte[] Select_App = {(byte)0x00,(byte)0xA4,(byte)0x04,(byte)0x00,(byte)0x04,(byte)0x50,(byte)0x54,(byte)0x4B,(byte)0x65};。。。。
他们工作得很好,我从卡片上得到了正确的回应。但我在android上试过这个命令。所以我认为字节转换是正确的,我们不需要转换任何东西
嗯,关于java.Smart can。*;我和您有同样的问题,我不能使用该图书发送任何命令。但是有人说,我必须使用一些java包装来发送一些命令。嗯..。我还在努力.:-)
发布于 2013-07-31 06:08:26
您需要通过以下方法正确地将字节转换为十六进制。
Integer class = StringUtil.parseHex("your class as string");类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;
}https://stackoverflow.com/questions/13822879
复制相似问题