我尝试从奥地利电子贺卡中读取信息以获得名字和姓氏。
现在有用的是:访问卡,发送APDU命令并以字节数组的形式获取信息。
如何将接收到的字节数组转换为XML以提取所需数据?
以下是代码:
import java.util.List;
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;
public class Main2 {
public static void main(String[] args) {
TerminalFactory factory = TerminalFactory.getDefault();
List<CardTerminal> terminals;
try {
terminals = factory.terminals().list();
CardTerminal terminal = terminals.get(0);
Card card = terminal.connect("*");
CardChannel channel = card.getBasicChannel();
// Select the MF
byte[] aid = { (byte) 0xD0, 0x40, 0x00, 0x00, 0x17, 0x01, 0x01, 0x01 };
ResponseAPDU resp = channel.transmit(new CommandAPDU(0x00, 0xA4, 0x04, 0x00, aid));
System.out.println("Response: " + resp.toString());
// Select the Personaladata-file
byte[] aid2 = { (byte) 0xEF, 0x01 };
resp = channel.transmit(new CommandAPDU(0x00, 0xA4, 0x02, 0x04, aid2));
System.out.println("Response: " + resp.toString());
// Get the data from the file
resp = channel.transmit(new CommandAPDU(0x00, 0xB0, 0x00, 0x00, 0xFF));
System.out.println("Response: " + resp.toString());
System.out.println("Response String: " + new String(resp.getData()));
card.disconnect(false);
} catch (CardException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
答案 0 :(得分:3)
我不确定如何将数据转换为XML结构(并根据什么模式)。但是,我从SV卡收到的字节数组看起来像ASN.1 DER编码的TLV结构:
30 xxxx SEQUENCE 30 18 SEQUENCE 06 08 OBJECT IDENTIFIER 2A28000A01040101 => OID 1.2.40.0.10.1.4.1.1 (SV number) 31 0C SET 12 0A NumericString nnnnnnnnddddmmmmyyyy => SV number: NNNN DDMMYY 30 0F SEQUENCE 06 08 OBJECT IDENTIFIER 2A28000A01040103 => OID 1.2.40.0.10.1.4.1.3 (Card sequence number) 31 03 SET 02 01 INTEGER xx => Card sequence number: xx 30 xx SEQUENCE [...] 30 xx SEQUENCE 06 03 OBJECT IDENTIFIER 55042A => OID 2.5.4.42 ({joint-iso-itu-t(2) ds(5) attributeType(4) givenName(42)}) 31 xx SET 0C xx UTF8String 4D69636861656C => Given name: "Michael" 30 xx SEQUENCE 06 03 OBJECT IDENTIFIER 550404 => OID 2.5.4.4 ({joint-iso-itu-t(2) ds(5) attributeType(4) surname(4)}) 31 xx SET 0C xx UTF8String 526F6C616E64 => Surname: "Roland" 30 xx SEQUENCE [...] 30 1D SEQUENCE 06 08 OBJECT IDENTIFIER 2B06010505070901 => OID 1.3.6.1.5.5.7.9.1 ({iso(1) identified-organization(3) dod(6) internet(1) security(5) mechanisms(5) pkix(7) pda(9) dateOfBirth(1)}) 31 11 SET 18 0F GeneralizedTime yyyyyyyymmmmdddd3132303030305A => Date of birth: YYYY-MM-DD 12:00:00Z 30 0F SEQUENCE 06 08 OBJECT IDENTIFIER 2B06010505070903 => OID 1.3.6.1.5.5.7.9.3 ({iso(1) identified-organization(3) dod(6) internet(1) security(5) mechanisms(5) pkix(7) pda(9) gender(3)}) 31 03 SET 13 01 PrintableString 4D => Gender: M (male)
所以这似乎遵循以下ASN.1表示法:
SVPersonGrunddaten ::= SEQUENCE OF Attribute
Attribute ::= SEQUENCE {
attributeName OBJECT IDENTIFIER,
attributeValue SET OF AttributeType }
AttributeType ::= CHOICE {
numericString NumericString,
integer INTEGER,
utf8String UTF8String,
time GeneralizedTime,
printableString PrintableString }
给定名称和姓氏的属性为
givenName Attribute ::= {
attributeName 2.5.4.42,
attributeValue { utf8String "Given Name" }
}
surname Attribute ::= {
attributeName 2.5.4.4,
attributeValue { utf8String "Surname" }
}
因此,为了获得给定的名称和姓氏,您将解析TLV结构,搜索这两个元素的OID,并将关联的值解码为UTF8字符串。
请注意,只是假设字段位于确切位置似乎不是一个好主意。例如,在给定名称字段之前有一个字段30 xx ...
(类型为Attribute
的字段),如果存在学术/职业标题,则该字段似乎仅存在(例如&#34; Dr。 &#34;在我的情况下)印在卡上。类似地,还有另一个学术后缀的可选字段(例如&#34; M.Sc。&#34;)只有在卡片上印有这样的后缀时才会出现。虽然我的卡片上的所有其他字段总是按照相同的顺序排列,但我不确定是否需要这样做。
答案 1 :(得分:1)
感谢提示,这里是将DER字节数组解码为String
的代码main